2011-06-12 101 views
10
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

回答

11

你在這裏看到的是因爲要求頂級聲明沒有參數單態。您可以在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