foldl和foldr?
foldl
和foldr
之间的区别只是循环的方向? 我认为他们所做的事情有所不同,而不仅仅是方向?
例如,如果你的函数不是关联的(例如,你括括表达式的方式很重要)
foldr (-) 0 [1..10] = -5
但foldl (-) 0 [1..10] = -55
。
在小范围内,这是因为10-(20-(30))
与((10)-20)-30
不相同。
鉴于(+)
是关联的(无论您添加子表达式的顺序如何),
foldr (+) 0 [1..10] = 55
, foldl (+) 0 [1..10] = 55
。 (++)
是另一个关联操作,因为xs ++ (ys ++ zs)
给出与(xs ++ ys) ++ zs
相同的答案(尽管第一个更快 - 不要使用foldl (++)
。
有些功能只能以一种方式工作:
foldr (:) :: [a] -> [a] -> [a]
但foldl (:)
是无稽之谈。
看看Cale Gibbard的图表(来自维基百科文章); 你可以看到f
获取调用与真正对不同的数据:
另一个不同之处在于,因为它匹配列表的结构,所以foldr
通常对懒惰评估更有效,所以只要f
在其第二个参数中非严格(如(:)
或(++)
)。 foldl
很少是更好的选择。 如果你使用foldl
,通常值得使用foldl'
因为它是严格的并且阻止你建立一长串中间结果。 (有关此问题的答案的更多信息,请参阅此主题。)
上一篇: foldl and foldr?
下一篇: foldl / foldr query