t
è un parametro di tipo della classe Tofu
di tipo * -> (* -> *) -> *
(scritto t :: * -> (* -> *) -> *
). Questo è il tipo dedotto di t
da parte di GHC perché, in assenza di -XPolyKinds
, GHC tenta di impostare tutti i parametri di tipo predefiniti su tipo *
. Quindi GHC assume che a
abbia tipo *
(sebbene nulla nella tua firma renda questa unica scelta).
Il tipo costruttore (->)
ha tipo* -> * -> *
. Poiché j a
viene visualizzato come parametro su (->)
, j a
deve avere il tipo *
. Dal momento che GHC ha ipotizzato che a
abbia tipo *
, restituisce qualcosa di tipo *
. Così:
j :: * -> *
Da t
viene applicato sia a
e j
, t
ha il tipo * -> (* -> *) -> *
, perché il primo argomento a
ha tipo *
e il secondo argomento j
ha tipo *->*
, e il tipo tuta t a j
must avere tipo *
poiché è anche un parametro del tipo (->)
.
Le classi sono solo i tipi che prendono parametri di tipo (proprio come data Foo a b
), ad eccezione Foo a b
ha tipo *
mentre Tofu t
è tipo un tipo speciale Constraint
. Così il tipo di Tofu
è:
(* -> (* -> *) -> *) -> Constraint
come GHC indica. Constraint
è solo il tipo di vincoli. Nella firma
(Num a) => a -> a -> a
(Num a)
è un tipo di tipoConstraint
.
Capisco quasi, ma sono un principiante. Puoi elaborare un po '? – orome
È un po 'meno criptico se guardo a ': t tofu', in realtà. Anche se sono ancora un po 'annebbiato. – orome
che lavora a un aggiornamento ora – crockeea