Questa domanda non è soggettiva. Nel libro di riferimento viene usato un verbo molto specifico, e mi piacerebbe capire qual è l'implicazione di quel fraseggio, perché temo di aver frainteso qualcosa.
Da Learn You a Haskell , il seguente paragrafo è il terzo e l'ultimo contenente "assumiamo *
".
data Barry t k p = Barry { yabba :: p, dabba :: t k }
E ora vogliamo renderlo un'istanza di
Functor
.Functor
vuole tipi di tipo,* -> *
maBarry
non sembra che abbia quel tipo. Di che tipo èBarry
? Bene, vediamo che ci vogliono tre parametri di tipo, quindi saràsomething -> something -> something -> *
. È sicuro dire chep
è un tipo concreto e quindi ha una specie di*
. Perchék
, supponiamo*
e quindi per estensione,t
ha una specie di* -> *
. Ora sostituiamo questi tipi con quellisomething
che abbiamo usato come segnaposto e vediamo che ha una specie di(* -> *) -> * -> * -> *
.
Perché stiamo assumendo qualcosa? Dopo aver letto "assumiamo X (cioè supponiamo che X sia vero)" è naturale per me pensare che dovremmo considerare anche il caso in cui X è falso. Nel caso specifico dell'esempio, non potrebbe t
essere di tipo (* -> *) -> *
e k
di tipo (* -> *)
? Se questo fosse il caso, qualunque sia t
e k
in realtà erano, t k
sarebbe ancora un tipo concreto, no?
Vedo che l'intera linea di ragionamento viene quindi verificata rispetto al compilatore, ma non credo che il compilatore presuma . In tal caso, vorrei sapere cosa, in caso contrario, temo di perdere il significato del paragrafo.
k :: L
per qualsiasi tipoL
, purchét :: L -> *
. Un compilatore qui deve tuttavia scegliere alcuni specificiL
o ricorrere a un poligono. Un poligono sarebbe l'opzione più generale, ma qui GHC sceglieL = *
(l'Haskell di base non ha poligami, devono essere attivati come estensione). Poiché sceglie qualcosa che è piuttosto arbitrario, LYAH usa la parola "assume" (AFAICT).