2016-10-14 174 views
1

我注意到在SML中有两种定义函数的方法。例如,如果你把add函数,这是两个方面:SML中int - > int - > int和(int * int) - > int有什么区别?

val add = fn : int -> int -> int 

第二个创建函数类型:

fun add x y = x+y; 

fun add(x,y) = x+y; 

与第一种方法创建函数类型

val add = fn : int * int -> int 

这两种类型对于相同功能有什么区别?还有为什么有两种类型的相同功能?

+0

在int - > int - > int的情况下,是因为currying哪里添加第一个接受一个int,返回另一个接受另一个int并返回final int的函数? –

+0

https://courses.cs.washington.edu/courses/cse341/09au/notes/notes07.html –

回答

5

如果我们从两个定义中删除语法糖它们变为

val add = fn x => fn y => x+y 

val add = fn xy => 
    case xy of 
     (x,y) => x+y 
在第一种情况下 add

所以是一个函数,参数x并返回另一个功能,它采用参数y,然后返回x+y。这种通过返回另一个函数来模拟多个参数的技术被称为currying。

在第二种情况下,add是一个函数,它将一个元组作为参数,然后添加元组的两个元素。

这也解释了两种不同的类型。 ->是功能箭头,它与右侧关联,意为int -> int -> intint -> (int -> int)相同,其描述的功能需要使用int并返回int -> int函数。

在另一方面*是用于的元组类型的语法,即int * int由含有两个整数,所以int * int -> int(其括号作为(int * int) -> int因为*具有比->更高的优先级)的元组的类型描述了一个函数,它两个int的元组并返回一个int。

+0

是的,你是对的。发现这篇关于在SML中卷曲的有用文章。 https://courses.cs.washington.edu/courses/cse341/09au/notes/notes07.html –

0

2功能不同的原因是因为Currying的现象。具体来说,柯里格是能够使用dom(f) = R^{n}作为函数编写任何函数,从Rn时间的输入。这基本上是通过确保每个输入返回一个函数来接收下一个变量来实现的。这就是->符号所表示的内容 - 这是Curry-Howard Isomorphism的基本结果。所以:

fun addCurry x y = x + y (* int -> int -> int *) 
fun addProd (x,y) = x + y (* (int*int) -> int *) 

告诉我们,addCurryaddProd还原成可以用于“替代品”,并返回变量的形式。因此,addProdaddCurry是Context-Equivalent。但是,它们是而不是语义相同。 (int*int)是产品类型。它表示它期望input1=intinput2=intint -> int表示需要int并返回int。这是一个箭头类型。

如果你有兴趣,你可能也想知道,只有2个类型的参数来SML功能:

1)令行禁止

2)元组 - 那么,fun addProd (x,y)代表(x,y)作为元组到函数参数。

相关问题