我常常在互联网上看到各类各样的抱怨,其余人的currying例子并非currying,但实际上只是部分应用。 html
我没有找到关于部分应用是什么的合理解释,或者它与currying有何不一样。 彷佛存在广泛的混淆,在某些地方将等效的例子描述为currying,在其余地方描述为部分应用。 编程
有人能够向我提供这两个术语的定义,以及它们如何区别的细节吗? 闭包
注意:这是从F#Basics中获取的,这是.NET开发人员进入函数式编程的优秀介绍性文章。 app
Currying意味着将具备许多参数的函数分解为一系列函数,每一个函数都接受一个参数并最终产生与原始函数相同的结果。 对于功能编程新手来讲,Currying多是最具挑战性的话题,特别是由于它常常与部分应用混淆。 您能够在此示例中看到二者都在工做: 函数式编程
let multiply xy = x * y let double = multiply 2 let ten = double 5您应该当即看到与大多数命令式语言不一样的行为。 第二个语句经过将一个参数传递给一个带两个的函数来建立一个名为double的新函数。 结果是一个函数,它接受一个int参数并产生相同的输出,就好像你已经调用了multiply,x等于2,y等于那个参数。 在行为方面,它与此代码相同: 函数
let double2 z = multiply 2 z一般,人们错误地认为乘法是造成双重的。 但这只是有点真实。 乘法函数是curry,可是在定义时会发生这种状况,由于默认状况下F#中的函数是curry。 当建立双重函数时,更准确地说,部分应用了乘法函数。 ui
乘法函数其实是一系列两个函数。 第一个函数接受一个int参数并返回另外一个函数,有效地将x绑定到特定值。 此函数还接受一个int参数,您能够将其视为绑定到y的值。 在调用第二个函数以后,x和y都被绑定,所以结果是x和y的乘积,如double体中所定义。 spa
要建立double,将计算乘法函数链中的第一个函数以部分应用乘法。 结果函数的名称为double。 当计算double时,它使用其参数以及部分应用的值来建立结果。 code
我在另外一个主题https://stackoverflow.com/a/12846865/1685865中回答了这个问题。 简而言之,部分函数应用程序是关于修复给定多变量函数的一些参数以产生具备较少参数的另外一个函数,而Currying是关于将N个参数的函数转换为返回一元函数的一元函数... [示例在这篇文章的末尾显示了Currying。] htm
Currying主要是理论上的兴趣:人们能够仅使用一元函数来表达计算(即每一个函数都是一元的)。 在实践中和做为副产品,若是语言具备curried功能,它是一种可使许多有用(但不是所有)部分功能应用程序变得微不足道的技术。 一样,它不是实现部分应用程序的惟一方法。 所以,您可能会遇到以其余方式完成部分应用程序的状况,但人们将其误认为是Currying。
(Currying的例子)
在实践中,人们不会只写
lambda x: lambda y: lambda z: x + y + z
或等效的JavaScript
function (x) { return function (y){ return function (z){ return x + y + z }}}
代替
lambda x, y, z: x + y + z
为了Currying。
对我来讲,部分应用程序必须建立一个新函数,其中使用的参数彻底集成到结果函数中。
大多数函数式语言经过返回闭包来实现currying:在部分应用时不要在lambda下求值。 所以,对于有趣的部分应用,咱们须要在currying和部分应用之间作出区别,并将部分应用视为curda和lambda下的评估。
经过如下JavaScript示例能够最好地说明curry和部分应用程序之间的区别:
function f(x, y, z) { return x + y + z; } var partial = f.bind(null, 1); 6 === partial(2, 3);
部分应用致使更小的功能; 在上面的例子中, f
的arity为3,而partial
只有2的arity。更重要的是,部分应用的函数会在调用时当即返回结果 ,而不是currying链中的另外一个函数。 所以,若是你看到像partial(2)(3)
这样的东西,它实际上不是部分应用。
进一步阅读:
有趣的问题。 通过一番搜索后, “部分功能应用程序没有进行调整”给出了我发现的最佳解释。 我不能说实际差别对我来讲特别明显,但后来我不是FP专家......
另外一个有用的页面(我认可我还没有彻底阅读)是“使用Java闭包进行Currying和部分应用程序” 。
看起来这看起来像是一对普遍混淆的术语,请注意。