之间的区别是foldl
and foldr
只是循环的方向?我认为他们所做的事情有所不同,而不仅仅是方向上的不同?
如果您的函数不具有关联性(即,用括号括起表达式的方式很重要),则存在差异,例如,
foldr (-) 0 [1..10] = -5
but foldl (-) 0 [1..10] = -55
.
这是因为前者等于1-(2-(3-(4-(5-(6-(7-(8-(9-(10 - 0)))))))))
,而后者是(((((((((0-1)-2)-3)-4)-5)-6)-7)-8)-9)-10
.
而因为(+)
是关联的(与添加子表达式的顺序无关),
foldr (+) 0 [1..10] = 55
and foldl (+) 0 [1..10] = 55
. (++)
是另一个关联运算,因为xs ++ (ys ++ zs)
给出相同的答案(xs ++ ys) ++ zs
(虽然第一个更快 - 不要使用foldl (++)
).
有些函数只能以一种方式工作:
foldr (:) :: [a] -> [a] -> [a]
but foldl (:)
纯属无稽之谈。
Have a look at Cale Gibbard's diagrams (from the wikipedia article http://en.wikipedia.org/wiki/Fold_(higher-order_function)); you can see f
getting called with genuinely different pairs of data:
另一个区别是,因为它与列表的结构匹配,foldr
对于惰性评估通常更有效,因此可以与无限列表一起使用,只要f
它的第二个参数是非严格的(比如(:)
or (++)
). foldl
很少是更好的选择。如果您正在使用foldl
通常值得使用foldl'
因为它很严格,会阻止您建立一长串中间结果。 (有关此主题的更多信息,请参见以下问题的答案这个问题 https://stackoverflow.com/questions/3429634/foldl-is-tail-recursive-so-how-come-foldr-runs-faster-than-foldl.)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)