Cerchiamo di essere sanguinosa. Dobbiamo quantificare tutto e dare il dominio della quantificazione. I valori hanno tipi; le cose di livello tipo hanno generi; i tipi vivono in BOX
.
f1 :: forall (k :: BOX).
(forall (a :: k) (m :: k -> *). m a -> Int)
-> Int
f2 :: (forall (k :: BOX) (a :: k) (m :: k -> *). m a -> Int)
-> Int
Ora, in nessuno dei due tipi esempio è k
quantificato esplicitamente, in modo GHC è decidere dove mettere che forall (k :: BOX)
, in base a se e dove k
è menzionato. Non sono del tutto sicuro di capire o sono disposto a difendere la politica come affermato.
Ørjan fornisce un buon esempio della differenza nella pratica. Andiamo sanguinosamente anche a questo. Scriverò /\ (a :: k). t
per rendere esplicita l'astrazione corrispondente a forall
e f @ type
per l'applicazione corrispondente. Il gioco è che possiamo scegliere gli argomenti @
, ma dobbiamo essere pronti a sopportare gli argomenti di /\
che il diavolo può scegliere.
Abbiamo
x :: forall (a :: *) (m :: * -> *). m a -> Int
e può di conseguenza scoprire che f1 x
è davvero
f1 @ * (/\ (a :: *) (m :: * -> *). x @ a @ m)
Tuttavia, se cerchiamo di dare f2 x
lo stesso trattamento, vediamo
f2 (/\ (k :: BOX) (a :: k) (m :: k -> *). x @ ?m0 @ ?a0)
?m0 :: *
?a0 :: * -> *
where m a = m0 a0
Il Il sistema di tipo Haskell tratta l'applicazione del tipo come puramente sintattica, quindi l'unico modo che l'equazione può essere risolto è identificando le funzioni e identificare gli argomenti
(?m0 :: * -> *) = (m :: k -> *)
(?a0 :: *) = (a :: k)
ma tali equazioni non sono nemmeno bene kinded, perché k
non è libero di essere scelto: è di essere /\
non -ED @
-ed.
Generalmente, per fare i conti con questi tipi di super-polimorfici, è bene scrivere tutti i quantificatori e poi capire come questo si trasforma in gioco contro il diavolo. Chi sceglie cosa e in che ordine. Lo spostamento di un forall
all'interno di un tipo di argomento cambia il selettore e spesso può fare la differenza tra vittoria e sconfitta.
Che cosa è esattamente 'k' lì? la variabile 'k' è qualcosa di speciale come' * '? – Sibi
@Sibi 'k' è una variabile tipo,' * 'è uno dei suoi possibili" valori ". In Haskell i tipi hanno i tipi più o meno allo stesso modo dei valori hanno tipi, anche se hai bisogno di estensioni per usare più dei tipi fissi incorporati come '*' e '* -> *'. –