问题描述
|
import Data.List (genericLength)
len = genericLength
:t genericLength
genericLength :: (Num i) => [b] -> i
:t len
len :: [b] -> Integer
为什么len
的类型与type2ѭ的类型不同?此处的目的是为genericLength
使用较短的别名。
在Haskell中不是一流的功能吗?难道不给函数取另一个名字会导致相同的函数吗?
解决方法
您在这里看到的是因为没有参数的顶级声明必须是单态的。您可以在Haskell Wiki上找到有关此原因的一些讨论,并在GHC用户指南中找到有关控制此行为的一些信息。
作为说明,请注意为
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
在这种特定情况下,我认为您还会得到不同的类型(而不是编译器错误),因为默认规则指定某些类型类应默认为特定类型(在这种情况下,“ 8”默认为“ 9”)。尝试用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报告中找到有关默认设置的一些信息。我还将提到GHC支持一种扩展的默认设置,该默认设置主要用于GHCi(默认情况下已启用),这有时会使人感到困惑。