Haskell为什么"Num x"需要"Show x"?

cha*_*oin 12 haskell

最近我用LYAH看了看Haskell .

我正在搞乱类型类并编写了这个快速测试函数:

foo :: (Num x) => x -> String
foo x = show x ++ "!"
Run Code Online (Sandbox Code Playgroud)

但是这会产生这个错误:

test.hs:2:9:
    Could not deduce (Show x) arising from a use of `show'
    from the context (Num x)
    bound by the type signature for foo :: Num x => x -> String
    at test.hs:1:8-29
    Possible fix:
      add (Show x) to the context of
        the type signature for foo :: Num x => x -> String
Run Code Online (Sandbox Code Playgroud)

但据LYAH说:

要加入Num,类型必须已经是Show和Eq的朋友.

所以,如果所有的Num的一个子集ShowEq,为什么我需要的类型签名更改为foo :: (Num x, Show x) => x -> String这个工作?难道不可能推断a Num也是可展示的吗?

Ben*_*mes 18

LYAH的信息很旧.GHC 7.4.1发行说明说:

Num类不再具有Eq或Show超类.

你需要写,

foo :: (Num x, Show x) => x -> String
Run Code Online (Sandbox Code Playgroud)

(事实上​​,foo你所写的不需要Num x,所以你可以省略它以避免不必要的约束.)

  • 它曾经是`class(Eq a,Show a)=> Num a where {...}`,现在它只是`class Num a where {...}`.没有必要将`Eq`和`Show`作为超类:一个`Num`实例并不意味着这些类中的任何一个的实例(如`Ord`暗示`Eq`),也不依赖于它们( `Num`没有定律,其'方法'的默认定义不是指'Eq`或`Show`).我认为这就是为什么`Num`成为一个独立的课程.较少的要求意味着该类允许更多的实例,例如`Num b => Num(a - > b)`. (6认同)
  • 值得注意的是,这是GHC的变化; Haskell标准仍然需要`Show`和`Eq`超类.从严格意义上讲,这使GHC成为一个非Haskell兼容的编译器; 然而,无论如何,这种变化很可能会进入下一个标准,就像很快就会出现`Applicative`将成为`Monad`的超类. (3认同)