【问题标题】:Ambiguity between Haskell Num class and my show-like classHaskell Num 类和我的表演类之间的歧义
【发布时间】:2011-05-18 18:08:12
【问题描述】:

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

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 有效,而我的班级却无效?我错过了什么吗?

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

【问题讨论】:

    标签: haskell types default typeclass


    【解决方案1】:

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

    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

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

    【讨论】:

      【解决方案2】:

      show 3 这样的东西首先起作用的原因是由于默认规则在涉及Num 类的歧义时选择特定类型。它不适用于您的 Some 类的原因是该规则规定所有涉及的类都必须是标准类(即,来自 Prelude 等)。这条规则的后半部分的观点有些愚蠢。

      【讨论】:

        【解决方案3】:

        问题:3 的类型是 Num a => a,但 ghc 需要具体类型才能搜索 Some 的实例 (可能在Num 中可能存在不止一个Some 实例——那么选择哪一个?)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多