准确地说,[42, 4, 2] 的类型是
Num a => [a]
这是因为 Haskell 中的整数字面量被视为前面有一个隐含的“fromIntegral”,所以真正的表达式是 [fromIntegral 42, fromIntegral 4, fromIntegral 2]。
"fromIntegral" 是 Num 类的一部分,具有类型
fromIntegral :: (Integral a, Num b) => a -> b
这表示它将某个 Integral 类型(即 Int 或 Integer)的实例转换为任意其他数值类型(Int、Float、Double、Complex ...)。这就是为什么你可以说“43.2 + 1”这样的话而不会出现类型错误。
“length [True]”将具有 Int 类型,因为“length”具有“[a] -> Int”类型,并且提供了参数(Bool 列表)。
“过滤偶数”有点复杂。从“过滤器”的类型开始:
filter :: (a -> Bool) -> [a] -> [a]
第一个参数(括号中的位)本身就是一个函数,它接受一个列表项并返回一个 Bool。请记住,Haskell 类型中的“->”运算符是右关联的,所以如果你放入隐含的括号中,你会看到类型是:
filter :: (a -> Bool) -> ([a] -> [a])
换句话说,如果你给它第一个参数,你会得到一个需要第二个参数的新函数。在这种情况下,第一个参数是:
even :: (Integral a) => a -> Bool
这引入了一个小问题:“偶数”要求它的参数是一个 Integral 类型(即 Int 或 Integer,如上所述),所以这个约束必须传播到结果。如果不是,那么你可以这样写:
filter even "foo"
因此答案是:
filter even :: (Integral a) => [a] -> [a]
可以看到 Integral 约束来自“even”类型,而其余类型来自“filter”。