Quelle est l'hypothèse formulée dans «Learn You a Haskell» lors de la déduction du genre?

18

Cette question n'est pas subjective. Un verbe très spécifique est utilisé dans le livre référencé, et j'aimerais comprendre quelle est l'implication de cette formulation, car j'ai bien peur de mal comprendre quelque chose.

De Learn You a Haskell , le paragraphe suivant est le troisième et dernier contenant "nous supposons *".

data Barry t k p = Barry { yabba :: p, dabba :: t k }  

Et maintenant, nous voulons en faire une instance de Functor. Functorveut des types de genre * -> *mais Barryne semble pas avoir ce genre. Quel est le genre de Barry? Eh bien, nous voyons qu'il faut trois paramètres de type, donc ça va être something -> something -> something -> *. Il est sûr de dire que pc'est un type concret et a donc une sorte de *. Car k, nous supposons *et donc par extension, ta une sorte de* -> * . Maintenant, remplaçons simplement ces types par les somethings que nous avons utilisés comme espaces réservés et nous voyons qu'il a une sorte de (* -> *) -> * -> * -> *.

Pourquoi supposons-nous quelque chose? En lisant «nous supposons X (c'est-à-dire que nous supposons que X est vrai)», il est naturel pour moi de penser que nous devrions également considérer le cas où X est faux. Dans le cas spécifique de l'exemple, ne pourrait-il pas têtre de nature (* -> *) -> *et kde nature (* -> *)? Si tel était le cas, quoi qu'il en soit tet en kréalité, ce t kserait toujours un type concret, non?

Je vois que toute la ligne de raisonnement est ensuite vérifiée par rapport au compilateur, mais je ne pense pas que le compilateur suppose . Si c'est le cas, j'aimerais savoir quoi, si ce n'est pas le cas, je crains de manquer le sens du paragraphe.

Enrico Maria De Angelis
la source
4
Vous avez raison. En effet, on peut en avoir k :: Lpour tout type L, aussi longtemps que t :: L -> *. Un compilateur ici doit cependant en choisir un spécifique L, ou recourir à une polykind. Une polykind serait l'option la plus générale, mais ici GHC choisit L = *(Haskell de base n'a pas de polykinds, ils doivent être activés en tant qu'extension). Puisqu'il choisit quelque chose qui est plutôt arbitraire, LYAH utilise le mot "assumer" (AFAICT).
chi
1
Ok, peut - être que le compilateur suppose que cela m'aurait intrigué au moins moins que nous ne le supposons , ou pas du tout.
Enrico Maria De Angelis

Réponses:

19

En fait, le compilateur suppose! Mais vous pouvez lui demander de ne pas le faire avec l'extension PolyKinds. Vous pouvez en lire plus en détail ici . Avec cette extension activée, le genre de Barrysera forall k. (k -> *) -> k -> * -> *.

Daniel Wagner
la source
-1

Bon point. L'auteur fait une supposition inutile. Peut-être juste pour le rendre plus facile à comprendre dans son chapitre Type Foo, mais des gens comme vous peuvent à juste titre remettre cela en question.

Les deux t, ket psont des variables de type. Comme nous le voyons, yabba :: pil peut vivre seul, c'est donc comme une fonction constante, comme s'il s'agissait d'une valeur au lieu d'un type, sa signature de type dirait Intou Char, peu importe ... vous l'appelez. Mais comme c'est un type, c'est sa signature aimable *.

Cependant, ttype ici prend une variable de type kpour construire un type ( dabba :: t k) donc nous sommes sûrs que (aucune supposition ici) tn'a une sorte de signature comme * -> *et ka* .

Une fois que nous savons cela ... la Barry t k psorte de signature du type est (* -> *) -> * -> * -> *ce qui signifie qu'il faut de ttemps en ktemps pet nous donner le Barrytype.

Modifier Assurez-vous de lire le commentaire de @ luqui ci-dessous.

Redu
la source
7
kn'est pas contraint d'être *comme vous le prétendez tout en déduisant t. Nous aurions pu k :: * -> *et t :: (* -> *) -> *, par exemple. Ajoutez un champ doo :: k Intà l'enregistrement et il passera sans problème.
luqui
@luqui .. Oui, vous avez raison ... Je ne supprimerai pas cette réponse, car votre commentaire vaut vraiment le coup.
Redu