工人的组合者的解释

什么是组合器?

它是“一个没有自由variables的函数或定义”吗?

或者怎么样呢?根据约翰·休斯 ( John Hughes)在他着名的关于箭头的论文中, “一个组合器是一个从程序片断中构build程序片断的函数” ,这是有利的,因为“…程序员使用组合器构造大部分期望的自动编程,而不是手写每一个细节“。 他继续说, mapfilter是这种组合filter的两个常见的例子。

一些符合第一个定义的组合器:

  • 小号
  • ķ
  • ÿ
  • 其他人从模拟一只知更鸟 (我可能是错的 – 我没有读过这本书)

一些符合第二个定义的组合器:

  • 地图
  • 过滤
  • 折合/减less(推测)
  • 任何>> =,撰写,fmap ?????

我对第一个定义不感兴趣 – 那些不会帮助我写出一个真正的程序(+1,如果你说服我,我错了)。 请帮我理解第二个定义 。 我认为map,filter和reduce是有用的:它们允许我在更高层次编程 – 减less错误,缩短和更清晰的代码。 以下是关于组合器的一些具体问题:

  1. 什么是更多的组合器例如地图,filter?
  2. 编程语言经常使用什么组合器?
  3. 组合器如何帮助我devise更好的API?
  4. 我如何devise有效的组合器?
  5. 什么是类似于非函数式语言(比如Java)的组合器,或者这些语言用什么来代替组合器?

更新

感谢@CA McCann,现在我对组合器有了更好的理解。 但是有一个问题对我来说仍然是一个棘手的问题:

使用组合器编写的函数式程序与不使用大量组合式程序之间的区别是什么?

我怀疑答案是,组合型的版本更短,更清晰,更一般,但如果可能的话,我希望能够进行更深入的讨论。

我也在寻找更多的常用编程语言中复杂组合器的例子和解释(比fold更复杂)。

我对第一个定义不感兴趣 – 那些不会帮助我写出一个真正的程序(+1,如果你说服我,我错了)。 请帮我理解第二个定义。 我认为map,filter和reduce是有用的:它们允许我在更高层次编程 – 减less错误,缩短和更清晰的代码。

这两个定义基本上是一回事。 第一个是基于正式的定义,你给的例子是原始的组合器 – 可能的最小的构build块。 他们可以帮助你写一个真正的程序,只要他们可以build立更复杂的组合器。 把S和K这样的组合器想象成一个假设的“组合电脑”的机器语言。 当然,实际的计算机并不是这样工作的,所以在实践中,通常会有其他方式在幕后执行更高级别的操作,但概念基础仍然是理解这些更高级别的意义的有用工具操作。

你给出的第二个定义是非正式的,并且是以更高级的函数的forms使用更复杂的组合器,这些函数以各种方式结合了其他函数。 请注意,如果基本构build块是上面的基本组合器,那么从它们构build的所有东西都是高阶函数和组合器。 然而,在存在其他原语的语言中,对于是或不是函数的东西有区别,在这种情况下,组合器通常被定义为一般以某种方式操纵其他函数的函数,function直接。

什么是更多的组合器例如地图,filter?

太多列出! 这两种方法都将描述单个值上的行为的函数转换为描述整个集合上的行为的函数。 您也可以具有转换其他函数的函数,例如将它们组合成端对端,或者分割和重新组合参数。 您可以使用组合器,将单步操作转换为生成或使用集合的recursion操作。 还是各种其他的东西,真的。

编程语言经常使用什么组合器?

这将会有所不同。 很less有完全generics的组合器 – 大部分是上面提到的原始组合器 – 所以在大多数情况下,组合器将会有一些意识到正在使用的任何数据结构(即使这些数据结构是由其他组合器构build的),其中通常情况下,有一些“完全通用”的组合器,然后是不同的人决定提供各种专业forms。 有一些荒谬的情况,地图,折叠和展开的(适当的概括版本)足以做几乎所有你可能想要的。

组合器如何帮助我devise更好的API?

正如你所说,通过考虑高层次的操作,以及那些相互作用的方式,而不是低层次的细节。

考虑“对于每个”风格的集合循环,这使您可以抽象枚举集合的细节。 在大多数情况下,这只是map / fold操作,通过使用combinator(而不是内置的语法),可以执行两个现有的循环,并以多种方式直接组合它们 – 一个接一个地做,等等 – 只需要一个组合器,而不是杂乱无章的一堆代码。

我如何devise有效的组合器?

首先,考虑一下你的程序使用的任何数据的操作是否有意义。 然后考虑如何将这些操作以通用的方式进行有意义的组合,以及如何将操作拆分成连接在一起的小块。 主要的是与转型操作 ,而不是直接的行动 。 当你有一个以不透明的方式执行一些复杂function的函数,只是吐出某种预先消化的结果时,你就无法做到这一点。 将最终结果留给使用组合器的代码 – 您希望从A点到B点的事情,而不是期望成为stream程开始或结束的事情。

什么是类似于非函数式语言(比如Java)的组合器,或者这些语言用什么来代替组合器?

Ahahahaha。 有趣的是,你应该问一下,因为对象实际上是高阶东西 – 它们有一些数据,但是它们也包含一些操作,而且很多构成好的OOPdevise的东西归结为“对象应该通常像组合器,而不是数据结构“。

所以可能最好的答案是这样的:代替类似combinator的东西,他们使用具有许多getter和setter方法或public字段的类,而逻辑主要由做一些不透明的预定义操作组成。