关于Haskell类型类(Num vs Read)

bab*_*bon 8 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)
Run Code Online (Sandbox Code Playgroud)

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

现在,按照上面的逻辑,我希望fromIntegral 4引发一个错误:

Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
Prelude> fromIntegral 4
4
Run Code Online (Sandbox Code Playgroud)

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

Prelude> fromIntegral 4 :: Int
Run Code Online (Sandbox Code Playgroud)

上班.

注意 - 我正在阅读"让你学习哈斯克尔以获得巨大的利益"并且已经涵盖到第5章了.我在第7章(或其他章节)中讨论的是什么?

谢谢.

ham*_*mar 12

它的工作原因是类型默认,这会导致模糊的类型变量默认为IntegerDouble(或其他一些用户定义的默认值).这只发生在Num及其子类中.

在GHCI,因拖欠规则放宽也对工作Show,Eq并且Ord,也()被添加到默认类型的列表.这允许表达式类似于[] == []检查.