fold

发布时间 2023-04-11 09:03:04作者: 牧羊龟
  • 一个fold接受一个二元函数,一个初始值(累加器)和一个要折叠的列表
  • 二元函数本身有两个参数
  • 使用初始值(累加器)和第一个(或最后一个)元素调用二元函数,生成的结果作为新的累加器
  • 然后用新的累加器和列表中新的第一项重新调用二元函数,依此类推
  • 最后只剩下一个累加器

foldl

如下

sum' = foldl (\ acc x -> acc + x) 0
elem' e = foldl (\ acc x -> if x == e then True else acc) False

foldr

如下

map' f = foldr (\ x acc -> f x : acc) []
  • foldr适用于无限列表,而foldl则不行
  • foldr会到达列表的开头,foldr则永远不会到达终点

fold在列表中逐项循环,然后返回一个值。当你想要遍历一个列表并返回一个值时,就可以使用fold

foldl1、foldr1

  • foldl1和foldr1函数与foldl和foldr非常相似,只是不需要输入起始值
  • 它们假设列表中的第一项(或最后一项)是开始值,然后开始按下一项折叠列表

foldl (flip (?) []

如下

reverse' = foldl (\ acc x -> x : acc) []
reverse' = foldl (flip (:)) []

scanl、scanr、scanl1、scanr1

  • scanl和scanr类似于foldl和foldr,只是它们以列表的形式返回所有中间累加器
  • scanl1和scanr1类似于foldl1和foldr1
    如下
scanl (+) 0 [3,5,2,1]
[0,3,8,10,11]

scanr (+) 0 [3,5,2,1]
[11,10,8,3,0]

scanl (flip (:)) [] [3,2,1]
[[],[3],[2,3],[1,2,3]]
  • 当使用scanl时,最终结果是列表最后一个元素
  • 当使用scanr时,最终结果时列表的开头