haskell - Haskell Num 类和我的类似表演的类之间存在歧义

标签 haskell types default typeclass

我正在尝试将我自己的数据通过适当的转换声明为类。我的代码如下所示:

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::Int)可以解决该问题,但非常不方便。
标准“Show”工作得很好,并且根据手册,它的声明方式完全相同。

为什么标准 Show 有效,但我的类(class)却无效?我错过了什么吗?

P.S.:显式“默认(Int)”无法解决此问题。

最佳答案

关于重载,你是对的。这有点棘手。首先,您必须提供类型签名来解决示例中的数字重载:

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是如何工作的呢?借助扩展默认规则的魔力。 Show 很特殊,GHCi 启用了一些特殊的默认规则来帮助“默认”type in arguments of Show to Integer .

您的新类不是扩展默认功能所了解的神奇类之一,因此遗憾的是,您将需要提供类型注释。

关于haskell - Haskell Num 类和我的类似表演的类之间存在歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6027017/

相关文章:

algorithm - 如何根据点列表有效地计算间隔列表?

Haskell: "where"子句中的类型变量与其父项位于同一命名空间中吗?

haskell - 无法理解以未部分应用的函数作为参数提供的高阶函数调用的结果

c++ - 在 C/C++ 中创建 10 位数据类型

types - Idris 中的 View - Idris 书中类型驱动开发的 list 10.5

svn - 如何更改访问本地SVN存储库的默认作者?

haskell - 从 [Maybe a] 中提取第一个 Just 值

javascript - 在 JavaScript 中检查变量是数字还是字符串

Delphi:如何避免文档文件夹设置中的重复(OneDrive)?

django - Django模型继承层次结构中字段的基于类的默认值