函数名称的别名具有不同的类型签名。为什么?

问题描述:

import Data.List (genericLength) 

len = genericLength 

:t genericLength 
genericLength :: (Num i) => [b] -> i 
:t len 
len :: [b] -> Integer 

为什么len的类型与genericLength的类型不同?此处的目的是为genericLength使用较短的别名。函数名称的别名具有不同的类型签名。为什么?

haskell函数不是一流的吗?不应该给另一个函数名称导致相同的功能?

+5

我不太了解这个问题,但我敢肯定这与[Monomorphism Restriction](http://www.haskell.org/haskellwiki/Monomorphism_restriction)有关。如果您在文件顶部放置了“{ - #LANGUAGE NoMonomorphismRestriction# - }”,它将按照您期望的方式行事。 – 2011-06-12 04:59:09

+0

+1给Jeffrey说,它与单态限制有关。 – 2011-06-12 07:10:31

你在这里看到的是因为要求*声明没有参数单态。您可以在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(默认情况下启用),偶尔会让人感到困惑。

+1

谢谢,想知道fI = fromIntegral。 – gorlum0 2011-06-12 05:06:41

+2

@ gorlum0:哈哈哈哈,单形和默认确实使这个功能尤其*无益。 – 2011-06-12 05:10:07

+1

请注意,不应该从GHC 7.8中发生,因为“GHCi中的默认情况下禁止单态限制”。 (https://downloads.haskell.org/~ghc/7.8.1-rc1/docs/html/users_guide/release-7-8-1.html) – thoferon 2015-05-12 10:40:01