当我询问+运算符的类型时,它就像你期望的那样
Prelude> :t (+)
(+) :: Num a => a -> a -> a
当我将操作符分配给变量时,类型签名会发生变化
Prelude> let x = (+)
Prelude> :t x
x :: Integer -> Integer -> Integer
为什么操作员的类型在分配时会发生变化?
答案 0 :(得分:8)
这是"可怕的单态限制"。基本上,当你定义一个
然后,默认情况下,Haskell试图变得聪明并为它选择一个不完全通用的类型。最初的原因是为了让Haskell更容易使用(没有它它可能更容易编写模糊类型的程序),但最近它似乎只是让每个人都绊倒,因为它是非常意想不到的行为。
决议?
提供类似
的类型注释let { x :: Num a => a -> a -> a; x = (+) }
在普通的Haskell代码中,最强烈推荐方法(3)。使用GHCi时,(1)和(2)更方便。