Je lis Fun With Phantom Types. Le premier exercice demande pourquoi il est nécessaire de fournir une signature aux fonctions opérant sur les types fantômes. Bien que je ne peux pas trouver une raison générale, je ne vois un problème dans l'exemple suivant:GADT: Y at-il une raison pour laquelle le type le plus faible ou le plus fort n'est pas choisi
data Expr a where
I :: Int -> Expr Int
B :: Bool -> Expr Bool
Add :: Expr Int -> Expr Int -> Expr Int
Eq :: (Eq a) => Expr a -> Expr a -> Expr Bool
whatIs (I _) = "an integer expression"
whatIs (Add _ _) = "an adition operation"
Maintenant, je comprends qu'il ya deux types possibles pour whatIs
ci-dessus, à savoir:
Expr a -> String
et
Expr Int -> String
cependant, le compilateur donne lieu une erreur:
• Couldn't match expected type ‘t’ with actual type ‘[Char]’
‘t’ is untouchable
inside the constraints: t1 ~ Int
bound by a pattern with constructor: I :: Int -> Expr Int,
in an equation for ‘whatIs’
at ti.hs:9:9-11
‘t’ is a rigid type variable bound by
the inferred type of whatIs :: Expr t1 -> t at ti.hs:9:1
Possible fix: add a type signature for ‘whatIs’
• In the expression: "someString"
In an equation for ‘whatIs’: whatIs (I _) = "someString"
• Relevant bindings include
whatIs :: Expr t1 -> t (bound at ti.hs:9:1)
Je me demande pourquoi le compilateur ne choisit aucun des deux.
Toute règle de désambiguïsation choisirait parfois le type "faux"; c'est-à-dire, il choisirait un type que l'utilisateur ne voulait pas. La décision a été d'échouer rapidement et de dire à l'utilisateur l'ambiguïté plutôt que de faire quelquefois la mauvaise chose, ce qui est une décision avec laquelle je suis d'accord. D'après mon expérience, il est généralement préférable de ne pas arriver tôt, plutôt que d'essayer de comprendre ce qui était réellement prévu et d'aller de l'avant avec un choix potentiellement erroné. –
ouais, je classerais ceci comme ghc essayant de se comporter selon le principe de la moins surprise – hao
Quand j'essaye de compiler ceci, j'obtiens une erreur parce que les valeurs de retour sont trop spécifiques pour un type inféré de 'Expr t1 -> t' . Cela semble être un problème autre que l'ambiguïté entre les types valides possibles. – chepner