将函数转换为无点样式会更改其类型

时间:2011-05-19 00:56:53

标签: haskell types monomorphism-restriction

我正在开始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

谢谢!

3 个答案:

答案 0 :(得分:12)

这称为monomorphism restriction

基本上,这意味着看起来像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