2009-08-28 75 views
15

這個問題的靈感來自此answer另一個問題時,表示可以使用的功能的列表中刪除所限定的元件的每次發生爲:Haskell的:類型推斷和功能組成

removeall = filter . (/=) 

工作出來從類型filter(/=)(.)鉛筆和紙,函數的類型爲

removeall :: (Eq a) => a -> [a] -> [a] 

這正是你會根據其合同的期望。然而,隨着GHCI 6.6,我得到

gchi> :t removeall 
removeall :: Integer -> [Integer] -> [Integer] 

,除非我明確指定的類型(在這種情況下正常工作)。爲什麼Haskell推斷這個函數的具體類型?

回答

28

爲什麼Haskell推斷這種函數的特定類型?

GHCi使用type defaulting來從一組可能值推斷出更具體的類型。您可以輕鬆地通過禁用the monomorphism restriction避免這種情況,

Prelude> :set -XNoMonomorphismRestriction 
Prelude> let removeall = filter . (/=) 
Prelude> :t removeall 
removeall :: (Eq a) => a -> [a] -> [a] 
17

還值得一提的是,如果你不指定一個名稱的表達,typechecker似乎避免違約類型:

Prelude> :t filter . (/=) 
filter . (/=) :: (Eq a) => a -> [a] -> [a]