关于Haskell类型类(Num vs Read)

时间:2015-07-05 08:20:53

标签: haskell

有人可以解释一下我在这里缺少的东西:

Prelude> :t read
read :: (Read a) => String -> a 
Prelude> read "4"

<interactive>:1:0:
    Ambiguous type variable `a' in the constraint:
      `Read a' arising from a use of `read' at <interactive>:1:0-7
    Probable fix: add a type signature that fixes these type variable(s)

read "4"引发错误,因为ghci不知道我们想要哪种具体类型,它只知道我们有一个Read类型类。 read "4" :: Int工作正常。这对我来说很清楚。

现在,按照上述逻辑,我希望fromIntegral 4引发错误:

Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
Prelude> fromIntegral 4
4

然而,它工作正常。为什么在这种情况下不需要类型注释?我预计上述情况会失败;并且只有

Prelude> fromIntegral 4 :: Int

工作。

注意 - 我正在阅读&#34;了解Haskell的好消息&#34;并且已经涵盖到第5章。我在第7章(或其他章节)中讨论了什么?

感谢。

2 个答案:

答案 0 :(得分:12)

它因type defaulting而起作用,导致模糊类型变量默认为IntegerDouble(或其他一些用户定义的默认值)。这仅适用于Num及其子类。

在GHCi中,Show也适用于EqOrd(),以及[] == []也会添加到默认类型列表中。这允许像before_action :set_locale private def set_locale I18n.locale = params[:locale] || I18n.default_locale end 这样的表达式键入check。

答案 1 :(得分:4)

区别在于read可能会导致任何类型,而fromIntegral会产生一个数字。 关于ghci中的数字有一些默认值,因此ghci可以使用默认类型。