首页 文章

Haskell - foldl和foldr?

提问于
浏览
44

foldlfoldr 之间的区别只是循环的方向?我认为他们做了什么,而不仅仅是朝这个方向有所不同?

1 回答

  • 93

    那里有's a difference if your function isn' t关联(即,你将表达式括在哪个方面很重要),例如,
    foldr (-) 0 [1..10] = -5foldl (-) 0 [1..10] = -55 .
    在小范围内,这是因为 10-(20-(30))((10)-20)-30 不同 .

    而因为 (+) 是关联的(无论您添加子表达式的顺序如何),
    foldr (+) 0 [1..10] = 55foldl (+) 0 [1..10] = 55 . (++) 是另一个关联操作,因为 xs ++ (ys ++ zs) 给出与 (xs ++ ys) ++ zs 相同的答案(尽管第一个更快 - 不要使用 foldl (++) .

    有些功能只能以一种方式工作:
    foldr (:) :: [a] -> [a] -> [a]foldl (:) 是胡说八道 .

    看看Cale Gibbard的图表(来自wikipedia article);你可以看到 f 被真正不同的数据对调用:

    foldr

    foldl

    另一个区别是因为它匹配列表的结构, foldr 对于延迟评估通常更有效,所以只要 f 在其第二个参数(如 (:)(++) )中是非严格的,就可以与无限列表一起使用 . foldl 很少是更好的选择 . 如果你正在使用 foldl 它通常值得使用 foldl' 因为它是严格的并且阻止你 Build 一长串的中间结果 . (有关this question的答案中有关此主题的更多信息 . )

相关问题