该论点按OCaml中的curried函数顺序排列

时间:2014-03-10 10:49:26

标签: ocaml

通常,我们会编写一个这样的函数

let abs_diff x y = abs (x-y)

我们也可以curried version

let abs_diff = fun x -> fun y -> abs(x-y)

我在这里写这个问题只是想确认我理解 currying

以下是我的理解:

  1. let abs_diff = fun x -> fun y -> abs(x-y)实际上返回一个带有一个参数fun y -> abs (x-y)的函数,在其中,x是参数

  2. 因此,当我们应用abs_diff 5 6时,它首先获取第一个参数5,返回一个函数fun y -> abs (5-y),然后继续应用于参数6,所以最终的结果是(fun y -> abs (5-y)) 6

  3. 我说错了吗?

    此外,对于一个函数应用程序来说,OCaml解释器就像utop一样,ocaml就像上面的第2点一样吗?

2 个答案:

答案 0 :(得分:2)

首先,两个写作

let abs_diff x y = abs (x-y)
let abs_diff = fun x -> fun y -> abs(x-y)

是等价的。它们都定义了类型

的相同功能
val abs_diff : int -> int -> int = <fun>

未经证实的版本将是

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

这是一个带有一个参数的函数,即(x,y)int*int个。


我不清楚你的意思

  

在其中,x是参数

您的意思是x替换参数吗?


abs_diff 5的调用返回closure,这是一个带有某些上下文的函数,真正发生了什么。像

这样的东西
fun y -> abs (x-y)   where   x = 5

当然等同于

fun y -> abs (5-y)

请注意,如果您需要,编译器可以将所有这些函数操作优化为简单的函数调用。

答案 1 :(得分:2)

让我补充一点:

OCaml中的功能始终是curry。这对初学者来说可能很奇怪。混淆可能是:我何时分配函数,何时函数结果?

# let sayhello  = print_endline "hello!";;
hello!
val sayhello : unit = ()
# let hello ()  = print_endline "hello!";;
val hello : unit -> unit = <fun>
# let h = hello;;
val h : unit -> unit = <fun>
# h ();;
hello!
- : unit = ()

sayhello被赋予执行print_endline的结果,即()。

hello是一个以()作为参数的函数。

h现在是相同的功能,未执行。如果参数在那里则执行。

我希望我说得更清楚。必须学会完全阅读顶级打印输出的类型信息。

语法还有一件事:

let f1 x y = x - y;;
let f2 = fun x y -> x - y;;
let f3 = function x -> function y -> x - y;;

这些定义产生相同的功能。您可以将fun与多个参数一起使用,但不能function

希望这有帮助。