15

我开始使用 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

谢谢!

4

3 回答 3

12

这称为单态限制

基本上,这意味着看起来像x =的顶级绑定被迫是非多态的,除非您指定类型签名。带参数的绑定,即f x =不受影响。有关为什么存在此限制的详细信息,请参阅链接。

通常,当应用限制时,您会收到一条错误消息,但在这种情况下,GHCi 能够使用类型默认值将类型更改Num a => aInteger.

躲避它的最简单方法是使用显式类型签名,或者将

{-# LANGUAGE NoMonomorphismRestriction #-}

在模块顶部,或使用-XNoMonomorphismRestriction.

于 2011-05-19T01:03:21.907 回答
3

正如其他人指出的那样,这是由称为“单态限制”的东西引起的。

MR 对 Haskell 编译器的编写者很有用,但对于在一般语言中是否值得使用 MR 存在争议。但有一点大家都同意:在 GHCi 提示符下,MR 只不过是个麻烦事。

在即将发布的 GHC 版本中,在这种情况下,MR 可能会默认关闭。现在,您应该在 GHCi 中禁用它,方法是.ghci在您的主目录中创建一个名为“”的文本文件,其中包含如下行:

:set -XNoMonomorphismRestriction
于 2011-05-19T09:23:34.260 回答
1

因为 的 定义g没有明确命名它的参数,所以你遇到了单态限制,防止g多态和(在这种情况下)导致 GHC 默认为Integer.

于 2011-05-19T01:03:16.323 回答