SML 中的 int -> int -> int 和 (int*int) -> int 有什么区别?
What is the difference between int -> int -> int and (int*int) -> int in SML?
我注意到在 SML 中有两种定义函数的方法。例如,如果您使用 add 函数,则有两种方法:
fun add x y = x+y;
fun add(x,y) = x+y;
第一种方法创建函数类型为:
val add = fn : int -> int -> int
第二个创建函数类型为:
val add = fn : int * int -> int
对于相同的功能,这两种类型有什么区别?还有为什么同一个功能有两种类型?
如果我们从您的两个定义中删除语法糖,它们将变为:
val add = fn x => fn y => x+y
和
val add = fn xy =>
case xy of
(x,y) => x+y
所以在第一种情况下 add
是一个函数,它接受一个参数 x
和 returns 另一个函数,它接受一个参数 y
然后 returns x+y
。这种通过返回另一个函数来模拟多个参数的技术称为柯里化。
第二种情况add
是一个函数,它接受一个元组作为参数,然后将元组的两个元素相加。
这也解释了两种不同的类型。 ->
是函数箭头,它关联到右边,意思是 int -> int -> int
与 int -> (int -> int)
相同,描述了一个接受 int
和 returns 的函数 int -> int
函数。
另一方面,*
是用于元组类型的语法,即 int * int
是包含两个整数的元组类型,因此 int * int -> int
(括号中为 (int * int) -> int
因为 *
的优先级高于 ->
) 描述了一个接受两个整数元组和 returns 一个整数的函数。
这两个函数之所以不同是因为 Currying
现象。具体来说,Currying 是一种能力,可以将具有 dom(f) = R^{n}
的任何函数编写为从 R
n
次获取输入的函数。这基本上是通过确保每个输入 return 是下一个变量接受的函数来实现的。这就是 ->
符号所代表的 - 它是 Curry-Howard Isomorphism
的基本结果。所以:
fun addCurry x y = x + y (* int -> int -> int *)
fun addProd (x,y) = x + y (* (int*int) -> int *)
告诉我们 addCurry
是 addProd
的简化形式,可以用于 "substitute" 和 return 变量。因此,addProd
和 addCurry
是上下文等效的。但是,它们 不是 语义等价的。
(int*int)
是产品类型。它说它期望 input1=int
和 input2=int
。 int -> int
说它需要一个 int
和 return 一个 int
。是箭型的。
如果您有兴趣,您可能还想知道 SML 函数只有两种参数:
1) 咖喱
2) 元组 - 因此,fun addProd (x,y)
将 (x,y)
表示为函数参数的元组。
我注意到在 SML 中有两种定义函数的方法。例如,如果您使用 add 函数,则有两种方法:
fun add x y = x+y;
fun add(x,y) = x+y;
第一种方法创建函数类型为:
val add = fn : int -> int -> int
第二个创建函数类型为:
val add = fn : int * int -> int
对于相同的功能,这两种类型有什么区别?还有为什么同一个功能有两种类型?
如果我们从您的两个定义中删除语法糖,它们将变为:
val add = fn x => fn y => x+y
和
val add = fn xy =>
case xy of
(x,y) => x+y
所以在第一种情况下 add
是一个函数,它接受一个参数 x
和 returns 另一个函数,它接受一个参数 y
然后 returns x+y
。这种通过返回另一个函数来模拟多个参数的技术称为柯里化。
第二种情况add
是一个函数,它接受一个元组作为参数,然后将元组的两个元素相加。
这也解释了两种不同的类型。 ->
是函数箭头,它关联到右边,意思是 int -> int -> int
与 int -> (int -> int)
相同,描述了一个接受 int
和 returns 的函数 int -> int
函数。
*
是用于元组类型的语法,即 int * int
是包含两个整数的元组类型,因此 int * int -> int
(括号中为 (int * int) -> int
因为 *
的优先级高于 ->
) 描述了一个接受两个整数元组和 returns 一个整数的函数。
这两个函数之所以不同是因为 Currying
现象。具体来说,Currying 是一种能力,可以将具有 dom(f) = R^{n}
的任何函数编写为从 R
n
次获取输入的函数。这基本上是通过确保每个输入 return 是下一个变量接受的函数来实现的。这就是 ->
符号所代表的 - 它是 Curry-Howard Isomorphism
的基本结果。所以:
fun addCurry x y = x + y (* int -> int -> int *)
fun addProd (x,y) = x + y (* (int*int) -> int *)
告诉我们 addCurry
是 addProd
的简化形式,可以用于 "substitute" 和 return 变量。因此,addProd
和 addCurry
是上下文等效的。但是,它们 不是 语义等价的。
(int*int)
是产品类型。它说它期望 input1=int
和 input2=int
。 int -> int
说它需要一个 int
和 return 一个 int
。是箭型的。
如果您有兴趣,您可能还想知道 SML 函数只有两种参数:
1) 咖喱
2) 元组 - 因此,fun addProd (x,y)
将 (x,y)
表示为函数参数的元组。