2014-10-08 87 views
1

我一直在试图理解SML中的高阶函数。我知道如何编写简单的高阶函数并且也理解签名。一个例子是:SML中高阶函数的签名

fun increment list = map (fn x=> x + 1) list; 
val it = fn: int list -> int list 

但是,我无法理解下面的高阶函数的签名:

fun add x y = x + y; 
val add = fn: int -> int -> int 

该功能可以写成:

fun add (x,y) = x+y; 
val add: fn : (int * int) -> int 

,我明白了。但在前面的函数中,我不明白操作的顺序是如何工作的。该函数是否同时采用两个参数,或者一次只需要一个参数,生成一个新的函数,然后生成所需的结果?它对于其他更高阶的函数将如何工作?

我需要为我的作业构建高阶函数签名的概念,以及在几周内提出的考试。

回答

1

在SML中,函数可以被调用。

- fun add x y = x + y 
    val add = fn : int -> int -> int 

是咖喱。这意味着它可以被部分应用,如:

- fun add2 x = add 2 x; 
    val add2 = fn: int -> int 
    - add2 3; 
    val it = 5 : int 

如果我们写的函数:

- fun add2tuple(x,y) = x + y; 
    val add2tuple = fn : (int * int) -> int 

我们实际上并没有传递两个参数,而是一个元组。元组包含两个整数是元组类型的描述。

  • 如果我们以curried形式编写函数,那么函数参数不会放在元组中。

  • 在咖喱形式中,函数fun f p1 p2 ... pn = ...可以通过在1和n-1参数之间传递来部分应用。

但其参数是一个元组不能被部分地施加的功能。

- fun addordered x y = x + (2 * y); 
val addordered = fn : int -> int -> int 
- addordered 2 3; 
val it = 8 : int 
- fun addordered2 x = addordered x 2; 
val addordered2 = fn : int -> int 
- addordered2 3; 
val it = 7 : int 

这个例子可以澄清,元组是一个单一的事情:

- fun add3tuple(x,y,z) = x + y; 
val add3tuple = fn : int * int * 'a -> int 
- add3tuple(3,4,5); 
val it = 7 : int 
- add3tuple(3,4,"Hello World"); 
val it = 7 : int 

希望您能喜欢丹·格罗斯曼的类。

1

有一点要记住的是,全部 SML函数只需要一个参数。这个参数可能是一对,就像在你的第二个add函数中一样,或者是一个int,就像你的第一个函数add一样。你是正确的,第一个add返回int -> int类型的函数。你也可以写

fun add1 x = fn y => x + y 

这使得它更清楚,它只需要一个参数。甚至

val add1 = fn x => fn y => x + y 

(FWIW,你double函数看起来有点奇怪。它忽略它的参数,而且每次返回相同的结果。

fun increment list = map (fn x => x + 1) list 

可能是你的意思。)

+0

是的,所以例如当你调用'add 2'时,你应该把它看作是取回函数'(fn y => 2 + y)',这个函数只需要替换所有出现的'x'值为'2'。 – RasmusWL 2014-10-08 14:09:05