2011-09-20 4 views
1

En apprenant plus sur le système de type Haskell, j'ai rencontré ce problème de jouet. Lorsque je compile le code suivant:Erreur Functor lors de l'utilisation d'une donnée dans une donnée: "impossible de construire le type infini"

data SingleData a = SingleData a Int String -- etc. 
data DataFail a = DataFail [SingleData a] 
instance Functor DataFail where 
    fmap f (DataFail xs) = DataFail (map f xs) 

Je reçois la redoutée "Survient vérifier: ne peut pas construire le type infini: b = b SingleData" message sur la définition de fmap. Étrangement, la même définition de fmap ne fonctionnera que si elle est en dehors de la déclaration d'instance:

fmapWorks f (DataFail xs) = DataFail (map f xs) 

Plus étrange encore, la mise en œuvre Monoid compile et fonctionne très bien:

instance Monoid (DataFail a) where 
    mempty = DataFail [] 
    mappend (DataFail xs) (DataFail ys) = DataFail (xs ++ ys) 

Je crois que c'est en quelque sorte suite à l'utilisation SingleData intérieur de DataFail, parce que cela fonctionne très bien ainsi:

data DataSuccess a = DataSuccess [a] 
instance Functor DataSuccess where 
    fmap f (DataSuccess xs) = DataSuccess (map f xs) 

Pourquoi Haskell se plaindre de la fonction fmap de DataFail, et que puis-je faire pour répare le?

+1

Si vous regardez le type de 'fmapWorks', vous verrez que ce n'est pas le type requis pour' fmap'. – augustss

Répondre

8

Le « Survient vérifier » erreur n'est pas que redoutée ...

Le problème est la fonction fournie à fmap. Essayez ceci:

instance Functor SingleData where 
    fmap f (SingleData a i s) = SingleData (f a) i s 

instance Functor DataFail where 
    fmap f (DataFail sds) = DataFail $ map (fmap f) sds 

Ainsi, l'erreur réelle est votre utilisation de map: le type ne correspond pas. Functor s'attend à ce qu'il soit de type a -> b, mais la façon dont vous l'utilisez est de type SingleData a -> SingleData b; l'instance Functor supplémentaire pour SingleData vous permet d'utiliser fmap pour appliquer directement la fonction à la valeur qui s'y trouve.

Questions connexes