2009-08-28 39 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]