2013-05-15 4 views
1

Dans le code Haskell suivant, la fonction typeError ne renvoie pas typecheck.Composition de la fonction Haskell - type déduit à tort

wrap x = [x] 

listf :: [[a]] -> [[a]] 
listf = id 

typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

typeError :: [a] -> [[a]] 
typeError = wrap . listf 

GHC produit cette erreur si elle est décommentée:

Couldn't match type `a' with `[a0]' 
    `a' is a rigid type variable bound by 
     the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1 
Expected type: [a] -> [a] 
    Actual type: [[a0]] -> [[a0]] 
In the second argument of `(.)', namely `listf' 
In the expression: wrap . listf 

Je ne comprends pas pourquoi. a devrait être en mesure d'unifier avec [a0] - ce sont des variables de type indépendantes. C'est exactement le type que l'on déduit pour typeCheck - mais pas lorsque l'opérateur . est utilisé.

étreintes produit un très similaire, et de la même fausse, message d'erreur:

ERROR "repro.hs":10 - Inferred type is not general enough 
*** Expression : typeError 
*** Expected type : [a] -> [[a]] 
*** Inferred type : [[a]] -> [[[a]]] 

De plus, cela fonctionne très bien:

listf' :: [a] -> [a] 
listf' = id 

typeCheck' :: [a] -> [[a]] 
typeCheck' = wrap . listf' 

Le problème ne se produit avec un [[a]] ou [ [[a]]] ou plus. Quel est le problème ici?

Répondre

5

Vous semblez avoir inversé la composition de la fonction ici.

-- This 
typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

-- is the same as 
typeCheck' :: [a] -> [[a]] 
typeCheck' = listf . wrap 

-- while this 
typeError :: [a] -> [[a]] 
typeError = wrap . listf 

-- is the same as 
typeError' :: [a] -> [[a]] 
typeError' x = wrap (listf x) 

Maintenant, il devrait être évident que cela ne fonctionne pas. listf exige que son argument soit [[a]], mais la signature de typeError affirme que cela fonctionne pour tout [a].

+0

Merde, c'est ce que j'obtiens pour essayer de réparer un bug dans ce code après des années de ne pas faire Haskell .. merci. – banana

Questions connexes