我在OCaml做了一个学校作业,我对表达的含义有疑问。
当我定义函数时,例如,我写道:
let iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
(int -> int)
是什么意思?我理解函数本身会收到一对作为参数,但我不完全理解括号的含义...
答案 0 :(得分:4)
括号用于消除类型(int -> int)
的函数之间的歧义 - 意味着它接受类型为int
的参数并返回int
- 并且可能只有两个常规{{1}作为该函数的参数。例如,如果没有第一对括号,您的int
将期望iter
元组,并且如果不存在其他参数,则期望(int, int)
作为返回类型。
请注意,第二对括号并不是绝对必要的,但它可以很好地指示您期望函数作为回报。如果没有这对括号,可以按照int -> int -> int
加上另一个(int, int -> int)
的元组来读取函数,例如返回int
。
与int
具有相同签名的函数示例可以是:
iter
答案 1 :(得分:1)
查找TL; DR以下。
在lambda演算中(请耐心等待),这就是ML语言的根源,核心思想是抽象应用程序或将函数映射到参数。 只有一个参数。
λx[x + 1]
上面的λ
将抽象函数x + 1
读入等待x
值的应用程序,防止其更改并应用(替换{{1}在函数中使用值并计算)。
Ocaml中的上述内容相当于:
x
,其类型为fun x -> x + 1
,或输入类型为int -> int
,输出类型为int
。现在,lambda一次只处理一个参数。如何处理具有多个参数的函数,如int
(多项式函数x*x -2*x + c
)?它像以前一样一次评估一个参数。
x2 − 2·x + c
因此,前一个应用程序的输出成为下一个应用程序的输入,依此类推。 Ocaml等价物将是
λc[λx[x*x - 2*x + c]]
该函数具有类型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
<强> TL; DR 强>
然而,使用括号对这些输入/输出链进行分组是棘手的,但在Ocaml中是必要的,因为实际上编译器无法从例如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 *)
如果您的意思是一个应用程序接受int * int -> int
对作为输入并返回int * int
作为输出(我们可以将其括号为int
)或者接受一个(int * int) -> int
一对int
和一个int -> int
类型的函数作为参数(可以写成int * (int -> int)
)。