2011-05-17 2 views
4

J'essaie de déclarer mes propres données avec la conversion appropriée en classe. Mon code ressemble à ceci:Ambiguïté entre la classe Haskell Num et ma classe de type show

data SomeData = SInteger Integer | SElse deriving Show 

class Some a where 
    toSome :: a -> SomeData 

instance Some Int where toSome = SInteger . toInteger 

main :: IO() 
main = print $ toSome 3 

Mais GHC (7.0.3) se met en colère et dit:

Ambiguous type variable `a0' in the constraints: 
     (Some a0) arising from a use of `toSome' 
       at minimal_broken.hs:11:16-21 
     (Num a0) arising from the literal `3' at minimal_broken.hs:11:23 
    Probable fix: add a type signature that fixes these type variable(s) 

signature de type explicite (comme 3 :: Int) résout le problème, mais il est très pratique .
Standard "Show" fonctionne très bien, et selon le manuel, il est déclaré exactement de la même manière.

Pourquoi Show standard fonctionne, mais pas ma classe? Ai-je manqué quelque chose?

P.S .: Explicite "default (Int)" ne résout pas cela.

Répondre

4

Vous avez raison concernant la surcharge. C'est un peu compliqué. Tout d'abord, vous aurez doivent donner une signature de type pour résoudre la surcharge numérique dans votre exemple:

Ambiguous type variable `a0' in the constraints: 
    (Some a0) arising from a use of `toSome' at A.hs:11:16-21 
    (Num a0) arising from the literal `3' at A.hs:11:23 

cela signifie, comme vous avez remarqué, que vous devez choisir un type de solution particulière, comme Int.

Alors, comment fonctionne Show? Par la magie de étendu des règles par défaut. Show est spécial, et GHCi permet certaines règles par défaut spéciales pour aider "par défaut" le type in arguments of Show to Integer.

Votre nouvelle classe ne fait pas partie des classes magiques connues par la fonctionnalité par défaut étendue, vous devrez donc tristement donner des annotations de type.

0

problème: le type de 3 est Num a => a, mais GHC a besoin d'un type concret afin de rechercher une instance de Some (peut-être, il pourrait exister plus d'une instance de Some qui est en Num - alors que l'on choisir?)

1

La raison pour laquelle quelque chose comme show 3 fonctionne en premier lieu est due à la règle par défaut qui sélectionne un type particulier lorsqu'il existe une ambiguïté impliquant la classe Num. La raison pour laquelle cela ne fonctionne pas avec votre classe Some est que la règle indique que toutes les classes impliquées doivent être des classes standard (c'est-à-dire, à partir du prélude, etc.). Cette dernière partie de la règle est un peu stupide dans l'opinion.

Questions connexes