为什么有些操作员在分配时会更改类型?

时间:2014-07-26 15:30:49

标签: haskell types ghci

当我询问+运算符的类型时,它就像你期望的那样

Prelude> :t (+)
(+) :: Num a => a -> a -> a

当我将操作符分配给变量时,类型签名会发生变化

Prelude> let x = (+)
Prelude> :t x
x :: Integer -> Integer -> Integer

为什么操作员的类型在分配时会发生变化?

1 个答案:

答案 0 :(得分:8)

这是"可怕的单态限制"。基本上,当你定义一个

  1. 新的顶级名称,
  2. 看起来不像函数定义
  3. 然后,默认情况下,Haskell试图变得聪明并为它选择一个不完全通用的类型。最初的原因是为了让Haskell更容易使用(没有它它可能更容易编写模糊类型的程序),但最近它似乎只是让每个人都绊倒,因为它是非常意想不到的行为。

    决议?

    1. 使用GHC 7.8。版本7.8之后,GHCi会话自动...
    2. 使用-XNoMonomorphismRestriction关闭此行为,或
    3. 提供类似

      的类型注释
      let { x :: Num a => a -> a -> a; x = (+) }
      
    4. 在普通的Haskell代码中,最强烈推荐方法(3)。使用GHCi时,(1)和(2)更方便。