柯里化:实际意义

Currying: practical implications

我对问题的理解来自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>

这两个函数的结果是一样的。 但是,实际上,是什么让这两个功能不同呢?可读性?计算效率?我缺乏经验,无法充分阅读这个问题。

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

let double = foo 2

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

首先,我想强调的是,由于编译器的优化,上述两个函数将被编译成相同的汇编代码。如果没有优化,柯里化的成本会太高,即柯里化函数的应用需要分配与参数数量相等的闭包数量。

在实践中,柯里化函数很有用,可以定义偏应用。例如,cf.,

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

另一个含义是,在柯里化形式中,您不需要为参数分配临时元组,如上例所示,函数 double2 将创建一个不必要的元组 (2,x)它被调用的时间。

最后,柯里化形式实际上简化了关于函数的推理,就像现在一样,我们没有 NN 元函数,我们只有一元函数。这允许平等地键入函数,例如,类型 'a -> 'b 适用于任何函数,例如 int -> intint -> int -> int 等。如果不使用柯里化,我们将需要添加一个数字将参数转换为函数类型,并带来所有负面后果。