【问题标题】:Signature of higher order functions in SMLSML 中高阶函数的签名
【发布时间】:2014-10-08 12:13:56
【问题描述】:

我一直在尝试理解 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 

据我了解。但是在前面的函数中,我无法理解操作顺序是如何工作的。该函数是一次采用两个参数,还是一次采用一个产生一个新函数,然后产生所需的结果?它如何适用于任何其他高阶函数?

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

【问题讨论】:

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


    【解决方案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
    

    我们实际上不是传入两个参数,而是一个元组。元组包含两个整数是对元组类型的描述。

    • 如果我们把函数写成柯里化形式,那么函数参数就不会放在一个元组中。

    • 在柯里化形式中,函数 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
    

    希望您喜欢 Dan Grossman 的课程。

    【讨论】:

      【解决方案2】:

      要记住的一点是,所有 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
      

      可能是你的意思。)

      【讨论】:

      • 是的,所以例如当你调用add 2时,你应该认为这是取回函数(fn y => 2 + y),它只是通过将所有出现的x替换为值@来获得987654332@.
      猜你喜欢
      • 1970-01-01
      • 2013-03-20
      • 2013-01-13
      • 2013-01-16
      • 1970-01-01
      • 2021-12-24
      • 2014-04-06
      • 1970-01-01
      • 2022-01-06
      相关资源
      最近更新 更多