foldr与foldl(或foldl')的含义
首先,我正在阅读的真实世界Haskell说永远不会使用foldl
,而是使用foldl'
。 所以我相信它。
但是我对什么时候使用foldr
vs. foldl'
很朦胧。 虽然我可以看到他们在我面前的工作方式不同,但我太愚蠢地无法理解何时“哪个更好”。 我想在我看来,它应该无关紧要,因为它们都产生相同的答案(不是吗?)。 事实上,我之前使用这个构造的经验来自Ruby的inject
和Clojure的reduce
,它们似乎没有“左”和“右”版本。 (侧面问题:他们使用哪个版本?)
任何能够帮助像我这样智能挑战的洞察力都将受到高度赞赏!
foldr fx ys
的递归,其中ys = [y1,y2,...,yk]
看起来像
f y1 (f y2 (... (f yk x) ...))
而foldl fx ys
的递归看起来像
f (... (f (f x y1) y2) ...) yk
这里的一个重要区别是,如果fxy
的结果只能使用x
的值计算,那么foldr
不需要检查整个列表。 例如
foldr (&&) False (repeat False)
返回False
而
foldl (&&) False (repeat False)
永不终止。 (注意: repeat False
会创建一个无限列表,其中每个元素都是False
。)
另一方面, foldl'
是尾递归和严格的。 如果你知道你不得不遍历整个列表(例如,将列表中的数字相加),那么foldl'
比foldr
更具有空间效率(可能更具时间效率)。
foldr
看起来像这样:
foldl
看起来像这样:
上下文:在Haskell wiki上折叠
它们的语义不同,所以你不能只交换foldl
和foldr
。 一个从左边折叠元素,另一个从右边折叠。 这样,运营商就可以按照不同的顺序申请。 这对所有非关联操作都很重要,例如减法。
Haskell.org有关这个主题的一篇有趣的文章。
链接地址: http://www.djcxy.com/p/80721.html