[英]Define functions with foldl foldr
I understand the definitions of foldl, foldr, but I have problems with functions defined by them. 我了解foldl,foldr的定义,但是它们定义的功能存在问题。
For example map with foldr: 例如,带有文件夹的地图:
map f [] = []
map f l = foldr (\x xs -> f x : xs) [] l
I don't understand the (\\x xs -> fx : xs)
. 我不明白
(\\x xs -> fx : xs)
。 It is the map function, which foldr takes? 是地图功能,哪个文件夹需要? But shouldn't it be
(\\x xs -> fx : f xs)
, because map f (x:xs) = fx : map f xs
? 但是不应该是
(\\x xs -> fx : f xs)
,因为map f (x:xs) = fx : map f xs
吗?
Example with foldl: foldl的示例:
concat (x:xs) = x ++ concat xs
concat' xs = foldl (++) [] xs
concat'' xs = foldl (\ys y -> ys ++ y) [] xs
Of course I understand (++)
, but what's the logic behind (\\ys y -> ys ++ y)
? 我当然理解
(++)
,但是(\\ys y -> ys ++ y)
背后的逻辑是什么? Is it ys = []
and y = xs
? 是
ys = []
和y = xs
吗? So the function takes []
as ys
and y
is the first element of xs
and concates the []
with the y
? 因此,该函数将
[]
设为ys
并且y
是xs
的第一个元素,并将[]
包含为y
? Concrete example: 具体示例:
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]
Another thing: concat
only takes 1 list xs
, so if I want to concat 2 lists? 另一件事:
concat
只接受1个列表xs
,所以如果我要concat 2个列表?
concat (x:xs) ys = x ++ concat xs ys
concat [1,2,3] [4,5,6] with foldl?
Reverse: 相反:
reverse (x:xs) = reverse xs ++ [x]
reverse' l = foldl (\xs x -> [x] : xs) [] l
reverse'' l = foldr (\x xs -> xs ++ [x]) [] l
The foldr is intuitive clear (with the questions from above), but what's behind the reverse order in foldl (\\xs x -> [x] : xs)
? 文件夹清晰直观(上面有问题),但是在文件夹
(\\xs x -> [x] : xs)
相反的顺序背后是什么? This foldl (\\x xs -> xs ++ [x]) [] l
would be wrong, wouldn't it? 这个文件
foldl (\\x xs -> xs ++ [x]) [] l
是错误的,不是吗?
Thanks a lot! 非常感谢!
The code 编码
foldr (\x xs -> ...) end list
could be read, roughly, as follows 可以大致如下读取
list
list
end
end
x
be the element at hand x
成为手头的元素 xs
be the rest of the list, after having been processed xs
为列表的其余部分 ...
operation ...
操作 The emphasized part is crucial. 强调的部分至关重要。
xs
is not the rest of the list, but the result of the "recursive call" on it. xs
不是列表的其余部分,而是列表上“递归调用”的结果。
Indeed, xs
is a bad name for that. 的确,
xs
是个坏名字。 In thee general case, it's not even a list! 在一般情况下,它甚至都不是列表! Eg one would never write (silly example)
例如,一个人永远不会写(愚蠢的例子)
foldr (\x xs -> x + xs) 0 [1..100] -- sum 1..100
but rather prefer something like 但宁愿喜欢这样的东西
foldr (\x partialSum -> x + partialSum) 0 [1..100] -- sum 1..100
(Actually, one would not sum using foldr
, but let's leave that aside.) (实际上,不会使用
foldr
求和,但我们将其放在一边。)
So, just read it like this: 因此,只需像这样阅读:
map f l = foldr (\x mappedTail -> f x : mappedTail) [] l
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.