这个问题的灵感来自于此answer到另一个问题,表明您可以使用定义为:
的函数从列表中删除每个元素。removeall = filter . (/=)
使用filter
,(/=)
和(.)
类型的铅笔和纸张进行操作,该函数的类型为
removeall :: (Eq a) => a -> [a] -> [a]
这正是您根据合约所期望的。但是,使用GHCi 6.6,我得到了
gchi> :t removeall
removeall :: Integer -> [Integer] -> [Integer]
除非我明确指定类型(在这种情况下它工作正常)。为什么Haskell推断出函数的这种特定类型?
答案 0 :(得分:28)
为什么Haskell推断出函数的这种特定类型?
GHCi正在使用type defaulting,从一组可能中推断出更具体的类型。您可以通过禁用the monomorphism restriction,
轻松避免这种情况Prelude> :set -XNoMonomorphismRestriction
Prelude> let removeall = filter . (/=)
Prelude> :t removeall
removeall :: (Eq a) => a -> [a] -> [a]
答案 1 :(得分:17)
值得注意的是,如果你没有为表达式指定名称,那么typechecker似乎避免了类型默认:
Prelude> :t filter . (/=)
filter . (/=) :: (Eq a) => a -> [a] -> [a]