2011-05-17 49 views
4

我想用适当的转换类声明我自己的数据。我的代码如下所示:Haskell Num类和我的类似节目之间的歧义

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 

但GHC(7.0.3)变得恼怒地说:

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) 

显式类型签名(如3 ::智力)修复该问题,但它是非常不方便。
标准的“显示”工作得很好,根据手册它的声明完全一样。

为什么标准显示作品,但我的班级没有?我错过了什么?

P.S .:明确的“default(Int)”不能解决这个问题。

回答

4

你说得对。这有点棘手。首先,你必须给一个类型签名解决您的示例数值超载:

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 

这意味着,当你发现,你必须选择一个特定的解决方案类型,如int。

那么Show如何工作?通过延期违约规则的神奇。显示是特殊的,GHCi启用一些特殊的违约规则来帮助“默认”type in arguments of Show to Integer

您的新课程并不是扩展默认功能知道的魔法课程之一,因此很遗憾,您需要提供类型注释。

0

的问题:3类型为Num a => a,但GHC需要一个具体类型,以搜索的Some实例 (可能的话,有可能存在的Some多个实例是在Num - 所以哪一个选择?)

1

之所以像摆在首位show 3作品是由于违约规则,挑选一个特定类型时,有涉及Num类的模糊性。它与你的Some类不起作用的原因是规则说所有涉及的类必须是标准类(即从前奏曲等)。这一规则的后半部分有点愚蠢。