Currying:实际意义

时间:2016-10-03 15:40:58

标签: ocaml currying

我对问题的理解来自Heilperin's et al. "Concrete Abstraction"。我得到的结论是对函数的求值的转换,该函数将几个参数用于评估函数序列,每个函数都有一个参数。我已经清楚了两种方法之间的语义差异(我可以这样称呼它们吗?)但我确信我没有掌握这两种方法背后的实际意义。

请考虑,在Ocaml:

# let foo x y = x * y;;
foo : int -> int -> int = <fun>

# let foo2 (x, y) = x * y;;
foo2 : int * int -> int = <fun>

两个功能的结果相同。 但是,实际上,这两个功能有什么不同呢?可读性?计算效率?我缺乏经验,没有给这个问题足够的阅读。

2 个答案:

答案 0 :(得分:3)

首先,我想强调,由于编译器优化,上面的两个函数将被编译成相同的汇编代码。如果没有优化,则currying的成本会过高,即,curried函数的应用需要分配一定数量的闭包,其数量等于参数的数量。

实际上,curried函数对于定义部分应用程序很有用。例如,cf。,

let double = foo 2
let double2 x = foo2 (2,x)

另一个含义是,在curry形式中,您不需要为参数分配临时元组,如上例所示,函数double2每次都会创建一个不必要的元组(2,x)叫做。

最后,咖喱表格实际上简化了关于函数的推理,就像现在一样,我们只有N个函数的N个家族,而不是一元函数。这允许,为了平等地键入函数,例如,类型'a -> 'b适用于任何函数,例如int -> intint -> int -> int等。如果没有curry,我们将需要添加一个数字参数函数的类型,带来所有负面后果。

答案 1 :(得分:1)

使用第一个实现,您可以定义,例如

let double = foo 2

第二个实现不能部分重用。