我对第一个定义不感兴趣-那些定义不会帮助我编写一个真实的程序(如果您确信我错了,则为+1)。请帮助我理解第二个定义。我认为map,filter和reduce很有用:它们使我可以进行更高级别的编程-错误更少,代码更短,更清晰。
这两个定义基本上是同一件事。第一个基于形式定义,您提供的示例是原始组合器 -可能的最小构建块。它们可以帮助您编写一个真正的程序,因为您可以使用它们构建更复杂的组合器。将诸如S和K之类的组合器视为一种假设的“组合计算机”的机器语言。当然,实际的计算机不会那样工作,因此在实践中,通常您会在幕后以其他方式实现更高级别的操作,但是概念基础仍然是了解这些更高级别含义的有用工具操作。
您给出的第二个定义是非正式的,是关于使用更复杂的组合器的,其形式是高阶函数,这些函数以各种方式组合了其他函数。请注意,如果基本构建块是上面的原始组合器,则从它们构建的所有内容都是高阶函数和组合器。但是,在存在其他原语的语言中,您会区分是功能还是非功能的事物,在这种情况下,组合器通常被定义为以一般方式操纵其他功能的功能,而不是对任何非功能进行操作的功能。直接发挥作用。
还有哪些组合器示例,例如地图,过滤器?
太多了!两者都将描述单个值行为的函数转换为描述整个集合行为的函数。您还可以具有仅转换其他功能的功能,例如端到端组成它们,或者拆分和重新组合参数。您可以具有将单步操作转换为产生或使用集合的递归操作的组合器。或其他各种东西,真的。
编程语言通常实现哪些组合器?
这将有很大的不同。完全通用的组合器相对较少(大多数是上面提到的原始组合器),因此在大多数情况下,组合器将对所使用的任何数据结构有所了解(即使这些数据结构仍然由其他组合器构建而成),其中在这种情况下,通常会有少数“完全通用”的组合器,然后有人决定提供各种专业形式。在许多情况下,映射,折叠和展开(适当的通用版本)足以完成几乎所有您想要的事情。
组合器如何帮助我设计更好的API?
就像您所说的那样,通过考虑高级操作及其交互方式,而不是低级细节来进行思考。
考虑一下“为每个”样式的循环在集合中的流行程度,它使您可以抽象出枚举集合的细节。在大多数情况下,这些操作只是映射/折叠操作,通过使用组合器(而不是内置语法),您可以执行以下操作,例如采用两个现有循环并以多种方式直接将它们组合在一起-彼此嵌套,一个接一个地执行,依此类推-仅应用组合器,而不是四处乱码。
如何设计有效的组合器?
首先,考虑对程序使用的任何数据有意义的操作。然后考虑如何以通用方式有意义地组合这些操作,以及如何将操作分解为较小的部分并重新连接在一起。最主要的是要进行转换和操作,而不是直接行动。当您拥有一个仅以不透明的方式执行某些复杂功能并且仅吐出某种预先消化结果的函数时,您将无能为力。将最终结果留给使用组合器的代码-您想要使您从A点到B点的东西,而不是希望成为过程开始或结束的东西。
与非功能语言(例如Java)中的组合器有什么相似之处,或者这些语言代替组合器使用什么?
啊哈哈哈哈 有趣的是,您应该问,因为对象首先是真正的高阶对象-它们具有一些数据,但是它们也进行了很多操作,并且构成良好的OOP设计的很多东西都归结为“对象应该通常就像组合器,而不是数据结构。”
因此,最好的答案可能是,它们使用具有大量getter和setter方法或公共字段的类,而不是类似组合器的类,并且逻辑主要由执行一些不透明的预定义动作组成。