另一个 Haskell 教程/语言进阶/解答
外观
< 另一个 Haskell 教程 | 语言进阶
Haskell | |
---|---|
另一个 Haskell 教程 | |
前言 | |
简介 | |
入门 | |
语言基础 (解答) | |
类型基础 (解答) | |
IO (解答) | |
模块 (解答) | |
高级语言 (解答) | |
高级类型 (解答) | |
单子 (解答) | |
高级 IO | |
递归 | |
复杂度 | |
函数 func3
无法转换为无点风格。其他看起来像
func1 x = map (*x) func2 f g = filter f . map g func4 = map (+2) . filter (`elem` [1..10]) . (5:) func5 = flip foldr 0 . flip . curry
你可能很想尝试将 func2
编写为 filter f . map
,试图通过 eta-reduction 去除 g
。在这种情况下,这是不可能的。这是因为函数组合运算符 (.
) 的类型为 (b -> c) -> (a -> b) -> (a -> c)
。在这种情况下,我们试图将 map
用作第二个参数。但是 map
接受两个参数,而 (.)
期望一个只接受一个参数的函数。
我们可以从一个递归定义开始
and [] = True and (x:xs) = x && and xs
从这里,我们可以很清楚地将它改写为
and = foldr (&&) True
我们可以递归地写成
concatMap f [] = [] concatMap f (x:xs) = f x ++ concatMap f xs
这暗示着我们可以写成
concatMap f = foldr (\a b -> f a ++ b) []
现在,我们可以进行点消除,得到
foldr (\a b -> f a ++ b) [] ==> foldr (\a b -> (++) (f a) b) [] ==> foldr (\a -> (++) (f a)) [] ==> foldr (\a -> ((++) . f) a) [] ==> foldr ((++) . f) []