回想 的类型(.)
。
(.) :: (b -> c) -> (a -> b) -> a -> c
它接受三个参数:两个函数和一个初始值,并返回两个函数组合的结果。
现在,函数对其参数的应用比(.)
运算符绑定得更紧密。所以你的表达:
map (*2) . filter even [1,2,3,4]
被解析为:
(.) (map (*2)) (filter even [1,2,3,4])
现在,第一个参数map (*2)
是可以的。它具有类型(b -> c)
、位置b
和c
位置Num a => [a]
。但是,第二个参数是一个列表:
Prelude> :t filter even [1,2,3,4]
filter even [1,2,3,4] :: Integral a => [a]
所以类型检查器会抱怨你在函数需要一个函数[a]
时将 a 作为参数传递。(.)
这就是我们所看到的:
Couldn't match expected type `a0 -> [b0]' with actual type `[a1]'
In the return type of a call of `filter'
In the second argument of `(.)', namely `filter even [1, 2, 3, 4]'
In the expression: map (* 2) . filter even [1, 2, 3, 4]
所以...括号!
使用$
运算符添加括号:
map (*2) . filter even $ [1,2,3,4]
或使用显式括号,删除两个函数的组合
map (*2) (filter even [1,2,3,4])
甚至:
(map (*2) . filter even) [1,2,3,4]