我正在开始Haskell ...我尝试用两种不同的方式编写以下简单的函数,让Haskell决定类型,类型系统在每种情况下做不同的事情。这种行为有什么解释?
Prelude> let f x = 2 * x
Prelude> let g = (2*)
Prelude> :info f
f :: Num a => a -> a -- Defined at <interactive>:1:5
Prelude> :info g
g :: Integer -> Integer -- Defined at <interactive>:1:5
谢谢!
答案 0 :(得分:12)
基本上,这意味着看起来像x =
的顶级绑定被强制为非多态,除非您指定了类型签名。带参数的绑定,即f x =
不受影响。有关此限制存在的原因,请参阅链接。
通常,在应用限制时会收到错误消息,但在这种情况下,GHCi可以使用类型默认将类型Num a => a
更改为Integer
。
避开它的最简单方法是使用显式类型签名,或者使用
{-# LANGUAGE NoMonomorphismRestriction #-}
位于模块顶部,或使用-XNoMonomorphismRestriction
运行GHCi。
答案 1 :(得分:3)
正如其他人所指出的那样,这是由“单态限制”引起的。
MR可能对Haskell编译器的编写者有用,并且对于是否值得使用该语言存在争议。但每个人都同意一件事:在GHCi提示下,MR只不过是一种麻烦。
在即将推出的GHC版本中,默认情况下,MR可能会被关闭。现在,您应该在GHCi中通过在主目录中创建一个名为“.ghci
”的文本文件来禁用它,该文件包含如下所示的行:
:set -XNoMonomorphismRestriction
答案 2 :(得分:1)
因为g
的定义没有明确地命名它的参数,所以你会遇到monomorphism restriction,阻止g
变成多态并且(在这种情况下)导致GHC默认为Integer
。