什么是高阶函数foldl和foldr的实际例子?

时间:2012-05-04 05:45:10

标签: functional-programming fold catamorphism

典型的学术范例是总结清单。 是否有现实世界中使用折叠的例子可以阐明其实用性?

3 个答案:

答案 0 :(得分:8)

fold可能是序列上最基本的操作。要求它的实用性就像在命令式语言中要求for循环的效用。

给定一个列表(或数组,或树,或......),起始值和函数,fold运算符将列表缩减为单个结果。它也是列表的自然catamorphism(析构函数)。

将列表作为输入并在检查列表元素后生成输出的任何操作都可以编码为折叠。 E.g。

sum      = fold (+) 0

length   = fold (λx n → 1 + n) 0

reverse  = fold (λx xs → xs ++ [x]) []

map f    = fold (λx ys → f x : ys) []

filter p = fold (λx xs → if p x then x : xs else xs) []

折叠运算符不是列表的特定,但可以统一的方式推广到“常规”数据类型。

因此,作为各种数据类型上最基本的操作之一,它确实有一些用处。能够识别算法何时可被描述为折叠是一种有用的技能,可以使代码更清晰。


参考文献:

答案 1 :(得分:1)

Lots And Lots Of foldLeft Examples列出了以下功能:

  • 总和
  • 产品
  • 计数
  • 平均
  • 最后
  • 倒数第二个
  • 包含
  • 获得
  • to string
  • 逆转
  • 独特
  • 设置
  • 插入排序
  • pivot(快速排行的一部分)
  • 编码(计算连续元素)
  • 解码(生成连续元素)
  • 组(进入偶数大小的子列表)

答案 2 :(得分:0)

我的蹩脚回答是:

  • foldr 用于将问题减少到原始情况,然后重新组装(表现为非尾递归)
  • foldl 用于减少问题并在每一步组装解决方案,在原始情况下,您已准备好解决方案(bahaves作为尾递归/迭代)

这个问题让我立刻想起了RalfLämmelGoing Bananas的演讲(因为rfold算子符号看起来像香蕉(|和|))。有很多说明性的例子,将递归映射到折叠,甚至折叠到另一个。

经典论文(起初相当困难)是Functional Programming with Bananas, Lenses,. Envelopes and Barbed Wire以其他运算符的外观命名。