Question

Cette question a été posée à la lecture du nouveau chapitre de l'excellent livre Learn You a Haskell sur les foncteurs d'application.

La classe Applicative a, comme partie de la définition de l’instance Maybe:

pure = Just

Si je vais simplement dans GHCi et importe Control.Applicative, et que je fais:

pure (3+)

Je ne comprends rien. Mais si je l'utilise dans une partie de l'expression:

pure (3+) <*> Just 4

Je reçois Just 7. Je suppose que cela n’est pas surprenant non plus, mais il me manque quelque chose de fondamental sur le fonctionnement des classes de types, je pense, qu’il n’ya aucune ambiguïté dans l’appel à pure ici.

Si ma confusion est logique, quelqu'un peut-il expliquer en détail ce qui se passe?

Était-ce utile?

La solution

C'est juste une inférence. L'opérateur (<*>) requiert que les deux arguments utilisent la même instance Applicative. Le côté droit est un Maybe, le côté gauche doit donc également être :t expression. C'est ainsi que l'on détermine quelle instance est utilisée ici. Vous pouvez consulter le type de toute expression dans l'interprète en tapant <=>. Si vous parcourez chaque sous-expression et examinez le type qui a été déduit, vous obtiendrez une meilleure image de ce qui se passe.

Autres conseils

Cela vaut la peine de regarder le type que le compilateur déduit pour pure (3+):

Prelude Control.Applicative> :t pure (3+)
pure (3+) :: (Num a, Applicative f) => f (a -> a)

Le type de ce terme est surchargé et la décision concernant la classe numérique et la classe applicative est reportée à une date ultérieure. Mais vous pouvez forcer un type particulier avec une annotation, par exemple:

*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double)
Just <function>

(Cela fonctionne car Showfun a une déclaration d'instance qui affiche une valeur de fonction sous la forme <function>.)

Il s’agit simplement de savoir quand le compilateur a accumulé suffisamment d’informations pour prendre une décision.

Pour développer un peu la réponse de newacct, s’il n’ya pas assez d’informations pour déduire le type réel, le compilateur peut (dans certains cas) essayer de sélectionner un type par défaut, limité à ceux qui satisferaient aux contraintes de type en question. . Dans ce cas, le type inféré est IO (n - & Gt; n) pour certaines instances difficiles à déterminer de Num = & Gt; n. GHCi l’évalue et jette la valeur de retour sans effet visible.

Voici un sujet SO relatif à l'inférence de type . Pas spécifique à Haskell, mais beaucoup de bons liens et de choses à lire sur l'inférence de types dans les langages fonctionnels.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top