函数名称的别名具有不同的类型签名。为什么?
问题描述:
import Data.List (genericLength)
len = genericLength
:t genericLength
genericLength :: (Num i) => [b] -> i
:t len
len :: [b] -> Integer
为什么len
的类型与genericLength
的类型不同?此处的目的是为genericLength
使用较短的别名。函数名称的别名具有不同的类型签名。为什么?
haskell函数不是一流的吗?不应该给另一个函数名称导致相同的功能?
答
你在这里看到的是因为要求顶级声明没有参数是单态。您可以在GHC用户指南中找到some discussion of the reasons for this on the Haskell wiki以及关于controlling this behavior的一些信息。
作为一种说明,注意给len
参数解决了这个问题:
len x = genericLength x
> :t len
len :: Num i => [b] -> i
因此,没有给它一个类型签名:
len :: (Num b) => [a] -> b
len = genericLength
也是如此关闭单态的限制:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.List (genericLength)
len = genericLength
> :t len
len :: Num i => [b] -> i
在这个特定的情况下,我认为你也会有所不同因为违约指定某些类型类别应该默认为特定类型的规则(在这种情况下,Num
默认为Integer
)的规则类型(而不是编译器错误)。如果你尝试用fmap
做同样的事情,你得到这个:
> :r
[1 of 1] Compiling Main (MonoTest.hs, interpreted)
MonoTest.hs:4:5:
Ambiguous type variable `f0' in the constraint:
(Functor f0) arising from a use of `fmap'
Possible cause: the monomorphism restriction applied to the following:
f :: forall a b. (a -> b) -> f0 a -> f0 b
(bound at MonoTest.hs:4:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the expression: fmap
In an equation for `f': f = fmap
Failed, modules loaded: none.
您可以找到有关在Haskell 98 Report违约的一些信息。我还会提到GHC支持一种扩展形式的默认设置,主要用于GHCi(默认情况下启用),偶尔会让人感到困惑。
我不太了解这个问题,但我敢肯定这与[Monomorphism Restriction](http://www.haskell.org/haskellwiki/Monomorphism_restriction)有关。如果您在文件顶部放置了“{ - #LANGUAGE NoMonomorphismRestriction# - }”,它将按照您期望的方式行事。 – 2011-06-12 04:59:09
+1给Jeffrey说,它与单态限制有关。 – 2011-06-12 07:10:31