SML中高阶函数的签名

时间:2014-10-08 12:13:57

标签: sml smlnj higher-order-functions operator-precedence

我一直在尝试理解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 
我明白了。但是在上一个函数中,我无法理解操作顺序是如何工作的。该函数是一次采用两个参数,还是一次生成一个新函数,然后产生所需的结果?它如何适用于任何其他更高阶函数?

我需要为我的作业建立关于高阶函数签名的概念,以及几周后我的考试。

2 个答案:

答案 0 :(得分:1)

要记住的一件事是所有 SML函数只接受一个参数。该参数可以是一对,如第二个{​​{1}}函数,或者一个int,就像在您的第一个add函数中一样。你是正确的,第一个add返回类型为add的函数。你也可以写

int -> int

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

fun add1 x = fn y => x + y

(FWIW,你的val add1 = fn x => fn y => x + y 函数看起来有点奇怪。它忽略了它的参数,每次都返回相同的结果。

double

可能就是你的意思。)

答案 1 :(得分: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

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

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

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

但是不能部分应用参数为单个元组的函数。

- 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

希望你喜欢Dan Grossman的课程。