这个函数签名在sml中是什么意思?

2023-11-30

我正在查看我的教授关于 SML 语言的一些注释,其中一个函数如下所示:

fun max gt = 
    let fun lp curr [] = curr
           | lp curr (a::l) = if gt(a,curr)
                             then lp a l
                             else lp curr l
in
    lp
end

有人可以帮忙解释一下这是做什么的吗?我最困惑的是这行:

    let fun lp curr [] = curr

这到底是什么意思?据我所知,有一个函数叫做lp但什么是curr []意思是?这些是论据吗?如果是的话,sml中不是只允许有一个参数吗?


代表着lp是一个带有 2 个参数的函数,第一个是curr第二个是一个列表,从逻辑上讲,它可能是空的([]) 或包含至少一个元素((a::l)是一个列表的模式,其中a位于头部,列表的其余部分是l).

如果将 FP 代码翻译成某种众所周知的命令式语言,它看起来会像:

function lp(curr, lst) {
  if (lst.length == 0) {  
    return curr;
  } else {
    var a = lst[0];                   // first element
    var l = lst.slice(1, lst.length); // the rest
    if (gt(a, curr)) {
      return lp(a, l);
    } else {
      return lp(curr, l)
    }
  }
}

虽然有点拗口,但翻译得很忠实。

函数式语言基于拉姆达演算,其中函数仅采用一个值并返回一个结果。虽然 SML 和其他 FP 语言基于此理论,但在实践中相当不方便,因此许多语言允许您通过所谓的方式来表达将多个参数传递给函数Currying.

所以,是的,在机器学习中,函数实际上只接受一个值,但柯里化可以让你模拟多个参数。

让我们创建一个名为的函数add,将 2 个数字相加:

fun add a b = a + b

应该这样做,但我们定义了 2 个参数。是什么类型的add?如果你看一下 REPL,它是val add = fn : int -> int -> int。其中写道,“add 是一个函数,它接受一个 int 并返回另一个函数(它接受一个 int 并返回一个 int)”

所以我们也可以定义add这边走:

fun add a = 
  fn b => a + b

你会发现他们很相似。事实上,在某种程度上可以肯定地说, 前者是后者的语法糖。 因此,您在 ML 中定义的所有函数,即使是具有多个参数的函数,实际上也是具有一个参数的函数,该函数返回接受第二个参数的函数,依此类推。一开始有点难以习惯,但它 很快就会成为第二天性。

fun add a b = a + b  (* add is of type  int -> int -> int *)

add 1 2 (* returns 3 as you expect *)

(* calling add with only one parameter *)

val add1 = add 1

What's add1?它是一个function这将添加1到您传递的单个参数!

add1 2 (* returns 3 *)

这是一个例子部分应用,您正在逐步调用函数, 一次一个参数,每次返回,另一个函数接受其余参数 的论点。

另外,还有另一种方法给出外观多个参数:元组:

(1, 2);     (* evaluates to a tuple of (int,int) *)

fun add (a,b) = a + b;

add (1, 2)  (* passing a SINGLE argument to a function that
               expects only a single argument, a tuple of 2 numbers *)

在你的问题中,lp 可以有也被实施为lp (curr, someList):

fun max gt curr lst = 
    let fun lp (curr, []) = curr
          | lp (curr, (a::l)) = if gt(a,curr) then lp (a, l)
                                else lp (curr, l)
in
    lp (curr, lst)
end

请注意,在这种情况下,我们必须声明max as max gt curr lst!

在您发布的代码中,lp显然是通过柯里化实现的。以及类型max本身就是fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a。拆开来看:

('a * 'a -> bool) ->  (* passed to 'max' as 'gt' *)   
    'a ->             (* passed to 'lp' as 'curr' *)
       'a list ->     (* passed to 'lp' as 'someList' *)
          'a          (* what 'lp' returns (same as what 'max' itself returns) *)

请注意type of gt,第一个参数max: fn : (('a * 'a) -> bool)- 它是一个函数one争论('a * 'a), 两个元组'a并返回一个'a。所以这里没有柯里化。

使用哪一种取决于品味、惯例和实际考虑。

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这个函数签名在sml中是什么意思? 的相关文章

  • 为什么这个函数要用括号括起来,后面还要加上括号? [复制]

    这个问题在这里已经有答案了 我一直在 javascript 源代码中看到这一点 但我从未真正找到使用此构造的真正原因 为什么需要这个 function stuff 为什么这样写呢 为什么不直接使用stuff本身而不是在函数中 编辑 我知道这
  • 将类型信息传递给 Scala 中的函数

    我有对 json 对象执行一些常见操作的代码 即提取 所以我想创建一个通用函数 它接受哪个类的类型参数 代码如下所示 def getMessageType T json JValue Either GenericError T try Ri
  • c++ - <未解析的重载函数类型>

    在我的班级里叫Mat 我想要一个将另一个函数作为参数的函数 现在我有下面 4 个函数 但是在调用 print 时出现错误 第二行给了我一个错误 但我不明白为什么 因为第一行有效 唯一的区别是功能f不是班级成员Mat but f2是 失败的是
  • $_GET 作为 PHP 函数中的参数

    我有同样的问题 但是 我根据使用标头的 if 语句将用户重定向到通过函数构造的动态页面 为了使该函数正常工作 需要在标头的 GET 部分中传递参数 根据提供的答案 这是一种不好的做法 我应该用什么方式来做呢 function page ti
  • C++17 中带有 noexcept 的 std::function

    在 C 17 中noexcept 已添加到类型系统中 http www open std org jtc1 sc22 wg21 docs papers 2015 p0012r1 html void r1 void f noexcept f
  • 将数据框列作为参数传递给 mutate 函数

    我有一张表 其中有五列 年份 GDP 收入 收入 和 工资 通过这张表 我用下面的代码进行了计算 library dplyr DATA TEST lt data frame Year c 2000 2001 2002 2003 2004 2
  • wordpressfunctions.php - 为每个帖子类别使用不同的页面模板

    我想连接到 save post 函数 找出帖子所属的类别 然后为每个类别中的帖子分配不同的页面模板 我已经尝试了大约 30 个不同的版本 但都没有成功 有人可以帮我指出正确的方向吗 add action save post assign c
  • 在 SQLServer 2005 函数中执行动态 SQL

    我在回答这个问题时会说 我不认为这是可以解决的 我还有一个解决方法 我可以创建一个带有输出的存储过程来完成此操作 使用函数对需要此校验和的部分进行编码会更容易 该代码将不起作用 因为Exec SP ExecuteSQL SQL来电 有人知道
  • Excel VBA 中.Delete 和.Clear 的区别?

    有什么区别Worksheets 1 Cells Delete and Worksheets 1 Cells Clear 我问这个是因为我一直用 Clear清除我的工作表内容 但在我之前的帖子中我发现Worksheets 1 Cells De
  • 函数名前的星号有什么作用?

    我对在大多数具有我不熟悉的函数声明的 C 程序中看到的内容感到困惑 void func name void param 什么是 暗示该功能 我的理解 在变量类型中的特点是它创建一个指向另一个变量的指针 因此它可以跟踪后一个变量存储在内存中的
  • 强制一个 javascript 函数等待运行,直到第一个函数完成

    下午 我遇到了一个问题 我需要运行一个函数 然后在完成后 运行下一个函数 并对四个函数执行此操作 我已经尝试了一段时间 试图找到正确的布局语法我的函数调用但似乎找不到任何东西来解决这个特定的场景 html div div div jquer
  • onclick 事件中未调用函数

    我想在每个 YouTube 链接的末尾添加一些 HTML 以在 litebox 中打开播放器 到目前为止 这是我的代码 document ready function var valid url new RegExp youtube com
  • Mysql 将 int 转换为 MAC

    我有一些数据可以转换 其中有 2 列 其中一列有 IP 它包含整数值 我在 mysql 查询中使用了以下函数 是否有一个函数可以用来转换我的 mac 列 其中包含整数和数据类型是bigint to MAC地址 SELECT INET NTO
  • 有没有一个 PHP 函数可以交换两个变量的值?

    比如说我有 var1 ABC var2 123 在某些条件下我想像这样交换两者 var1 123 var2 ABC 是否有一个 PHP 函数可以执行此操作 而不必创建第三个变量来保存其中一个值 然后重新定义每个值 就像这样 var3 var
  • 将数组传递给函数 - 指针与引用(C++ 与 C)

    我有一个关于将数组传递给函数的最佳实践的广泛问题 因此 过去当我用 C 语言编程时 我想要一个函数的输入是一个数组 我会声明该函数的输入参数是一个指针 这效果相对较好 然而 我已经开始更多地使用 C 进行编程 并试图确定将数组传递到函数中的
  • 可以声明对 Rust 中未使用的结果发出警告的函数吗? [复制]

    这个问题在这里已经有答案了 Rust 是否有办法声明一个函数 对于任何类型 不使用其结果都会发出警告 类似于 GCC 的东西 attribute warn unused result 自 1 27 起 must use 也适用于函数 看来
  • putc 和 ungetc 和有什么区别?

    int ungetc int c FILE fp 将字符 c 推回 fp 并返回 c 或EOF对于一个错误 其中 intputc int c FILE fp 将字符 c 写入文件 fp 并返回写入的字符 或者EOF对于一个错误 这些是 K
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • 解析,用三点参数替换

    让我们考虑一个典型的deparse substitute R call f1 lt function u x y print deparse substitute x varU vu varX vx varY vy f1 u varU x
  • R 中的字符串作为函数参数

    数据框chocolates列出了糖果的类型以及每种糖果的一组评级 ID sweetness filling crash snickers 0 67 0 55 0 40 milky way 0 81 0 53 0 56 我正在编写一个函数 它

随机推荐