Function (int->;int)>;(int->;int)是什么意思?

Function (int->;int)>;(int->;int)是什么意思?,function,types,syntax,ocaml,Function,Types,Syntax,Ocaml,我正在用OCaml做一个学校作业,我有一个关于表达式含义的问题 例如,在定义函数时,我写道: let iter : int * (int -> int) -> (int -> int) = fun (n,f) -> (int->int)是什么意思?我理解函数本身接收一对作为参数,但我不完全理解括号的含义…括号用于消除(int->int)类型函数之间的歧义-意味着它接受类型为int的参数,并返回一个int-可能只有两个常规int作为该函数的参数。例如,如果没有第一对括号,

我正在用OCaml做一个学校作业,我有一个关于表达式含义的问题

例如,在定义函数时,我写道:

let iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->

(int->int)
是什么意思?我理解函数本身接收一对作为参数,但我不完全理解括号的含义…

括号用于消除
(int->int)类型函数之间的歧义
-意味着它接受类型为
int
的参数,并返回一个
int
-可能只有两个常规
int
作为该函数的参数。例如,如果没有第一对括号,您的
iter
将期望一个
(int,int)
元组,如果没有其他参数,则期望返回类型为
int->int->int

请注意,第二对括号并不是绝对必要的,但它可以很好地指示您希望得到一个函数作为回报。如果没有这对括号,函数可以被读取为一个元组
(int,int->int)
加上另一个
int
,例如返回一个
int

与您的
iter
具有相同签名的函数示例如下:

let random_func: int * (int -> int) -> (int -> int) =
     fun (n, f) -> f

括号用于消除类型为
(int->int)
的函数之间的歧义,这意味着它接受类型为
int
的参数并返回一个
int
,可能只有两个常规的
int
作为该函数的参数。例如,如果没有第一对括号,您的
iter
将期望一个
(int,int)
元组,如果没有其他参数,则期望返回类型为
int->int->int

请注意,第二对括号并不是绝对必要的,但它可以很好地指示您希望得到一个函数作为回报。如果没有这对括号,函数可以被读取为一个元组
(int,int->int)
加上另一个
int
,例如返回一个
int

与您的
iter
具有相同签名的函数示例如下:

let random_func: int * (int -> int) -> (int -> int) =
     fun (n, f) -> f
找到TL;下面是博士

在lambda演算(请记住我的话)中,ML语言的根基就是lambda演算,其核心思想是抽象应用程序或将函数映射到参数只有一个参数

λ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)

太长了,读不下去了。 在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]]
因此,前一个应用程序的输出将成为下一个应用程序的输入,依此类推

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;