【发布时间】:2016-11-05 06:31:51
【问题描述】:
我了解 foldl、foldr 的定义,但我对它们定义的函数有疑问。
例如带有 foldr 的地图:
map f [] = []
map f l = foldr (\x xs -> f x : xs) [] l
我不明白(\x xs -> f x : xs)。是map函数,foldr取哪个?但是不应该是(\x xs -> f x : f xs),因为map f (x:xs) = f x : map f xs吗?
以 foldl 为例:
concat (x:xs) = x ++ concat xs
concat' xs = foldl (++) [] xs
concat'' xs = foldl (\ys y -> ys ++ y) [] xs
我当然理解(++),但(\ys y -> ys ++ y) 背后的逻辑是什么?是ys = [] 和y = xs 吗?
因此,该函数将[] 视为ys,而y 是xs 的第一个元素,并将[] 与y? 连接起来。
具体例子:
concat'' [1,2,3] = foldl (\ys y -> ys ++ y) [] [1,2,3]
=> foldl (\ys y -> ys ++ y) ((\ys y -> ys ++ y) [] [1]) [2,3]
=> foldl (\ys y -> ys ++ y) [1] [2,3]
=> foldl (\ys y -> ys ++ y) ((\ys y -> ys ++ y) [1] [2]) [3]
=> foldl (\ys y -> ys ++ y) [1,2] [3]
=> foldl (\ys y -> ys ++ y) ((\ys y -> ys ++ y) [1,2] [3]) []
=> foldl (\ys y -> ys ++ y) [1,2,3] []
=> [1,2,3]
另一件事:concat 只需要 1 个列表 xs,所以如果我想连接 2 个列表?
concat (x:xs) ys = x ++ concat xs ys
concat [1,2,3] [4,5,6] with foldl?
反向:
reverse (x:xs) = reverse xs ++ [x]
reverse' l = foldl (\xs x -> [x] : xs) [] l
reverse'' l = foldr (\x xs -> xs ++ [x]) [] l
foldr 很直观(上面有问题),但是 foldl (\xs x -> [x] : xs) 的相反顺序背后是什么?这个foldl (\x xs -> xs ++ [x]) [] l 是错误的,不是吗?
非常感谢!
【问题讨论】:
-
这是几个问题 - 首先观察
xs已经 由f映射(查看foldr的定义以了解原因) (f xs也不会像f :: a -> b和f :: [a] -> b'那样被很好地键入,所以你需要识别a ~ [a]) -
请注意
foldr f z [x1, x2, x3] = f x1 (f x2 (f x3 z))所以xs已经被f映射。 -
第二个:只需注意
foldl将从左侧循环通过xs(再次查看定义) -
最后:这只是从左折叠与从右折叠之间的区别 - 只需尝试不同的实现并自己看看!
标签: haskell dictionary functional-programming fold