import Data.List (genericLength)
len = genericLength
:t genericLength
genericLength :: (Num i) => [b] -> i
:t len
len :: [b] -> Integer
为什么len
的类型与genericLength
的类型不同?这里的目的是为genericLength
使用较短的别名。
haskell中的函数不是一流的吗?不应该为功能结果赋予相同功能的其他名称吗?
答案 0 :(得分:12)
您在这里看到的是因为要求顶级声明没有参数是单态。您可以在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(并默认在那里启用),这偶尔会让人感到困惑。