在下面找到 TL;DR。
在 lambda 演算(请耐心等待)中,这是 ML 语言的根源,其核心思想是关于抽象应用程序或函数到参数的映射。 只有一个参数。
λx[x + 1]
上面的λ将抽象函数x + 1读入一个等待x的值的应用程序中,防止它改变,然后应用(将函数中的x替换为该值并计算)。
Ocaml 中的上述内容相当于:
fun x -> x + 1
类型为int -> int,或输入类型为int,输出类型为int。现在,lambda 一次只处理一个参数。这如何与具有多个参数的函数一起使用,例如x*x -2*x + c(多项式函数x2 − 2·x + c)?它像以前一样一次评估一个参数。
λc[λx[x*x - 2*x + c]]
因此,前一个应用程序的输出成为下一个应用程序的输入,依此类推。 Ocaml 等价物是
fun c x -> (x * x) - (2 * x) + c
函数的类型为 int -> int -> int 或 (int -> int) -> int(输入链 -> 输出)如果将函数部分应用于参数 x = 3,则会得到一个简化的函数,如下所示:
fun c 3 -> (3 * 3) - (2 * 3) + c
fun c -> 9 - 6 + c
fun c -> 3 + c
结果函数的类型为int -> int。这是柯里化的基础。起初它可能看起来令人困惑,但事实证明它在命令式语言中非常有用且未被充分重视。例如,您可以这样做:
let waiting_for_c_and_x = fun c x -> 2*x + c
let waiting_for_c = waiting_for_c_and_x 10 in
let result = waiting_for_c 2 (* result = 22 *)
TL;DR
但是,在 Ocaml 中使用括号对这些输入/输出链进行分组虽然很棘手但很有必要,因为实际上编译器无法从例如int * int -> int 如果您的意思是应用程序接受 int * int 对作为输入并返回 int 作为输出(我们可以将其括为 (int * int) -> int)或接受 int 对和函数的应用程序类型为int -> int 作为参数(可以写成int * (int -> int))。
从Stanford Encyclopedia of Philosophy (very good read)申请