ml - 标准 ML 中的函数声明 `f x y` 和 `f (x, y)` 有什么区别?

标签 ml

在Standard ML中,以下声明有什么区别(我省略了以=开头的定义):

fun f x y;

fun f (x, y);

据我所知,第一个接受两个参数,而第二个接受一个元组。如果是这样,那么使用一个与另一个的(实际)含义是什么?可以争论哪种是最好的风格吗?假设,实际上并不需要将元组作为一个整体来使用,即只有 xy 分别是相关的。

最佳答案

是的,正如您所说,第一个接受“两个参数”,而第二个接受一个元组参数。但是,要了解真正发生的事情,您必须了解柯里化(Currying)。在 ML 中,每个“函数”都只接受一个参数(不多也不少)。

第二种情况,这个很好理解,它有一个参数,就是一个元组,对元组中的东西做一些事情,返回一个结果。在第一种情况下,您正在定义一个接受一个参数的函数,然后返回一个接受另一个参数的函数,然后返回结果。

例如,这是一个接受两个 int 并返回一个 int 的函数。查看这两个函数的类型是有启发性的:第二个函数的类型是 (int * int) -> int,即从元组到 int 的函数。第一个函数的类型是 int -> int -> int,因为 -> 是右结合的,可以解析为 int -> (int -> 整数)。所以你可以看到,它接受一个 int 并返回一个函数。语法 fun f x y = ... 是更冗长的 val f = fn x => fn y => ... 的语法糖。当您应用此功能时,例如f 3 4,函数应用程序是左结合的,所以它实际上是 (f 3) 4,所以你可以看到它是如何工作的:f 采用 int,返回一个函数,然后将其应用于另一个 int。这就是柯里化(Currying)的要点。 ML 的语法简单易行。

柯里化(Currying)版本(第一个版本)允许您进行部分应用。这意味着,虽然你的函数在概念上有两个参数,但你不必给它那么多参数。所以我们上面的 f 3 4(它是 (f 3) 4),如果我们只是采用 f 3,而不是只是将其应用于4,只是保留它并将其存储在变量或其他东西中?通过“给函数比它想要的更少的参数”,我们自动得到一个接受剩余参数的函数。例如,我们可以执行 map (f 3) someList,它将为列表中的每个 x 计算一个 f 3 x 的列表,无需我们编写一些复杂的语法。

在标准 ML 中,库函数大多采用非柯里化(Currying)形式;而在 OCaml 和 Haskell 中,它们大多采用 curry 形式。 (参见 this question。)但是,作为高阶函数的 SML 库函数(如 map 和 fold)倾向于将它们的函数参数放在单独的(柯里化(Currying))参数中。

关于ml - 标准 ML 中的函数声明 `f x y` 和 `f (x, y)` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13068982/

相关文章:

functional-programming - 在不使用 case 语句的情况下“解压”SML DataType 中的数据

haskell - 将 ML 风格的模块添加到 Haskell 的主要理论困难是什么?

functional-programming - SML Ml 编程函数是具有 bool 条件的旧日期

type-inference - 机器学习中类型推断的局限性

functional-programming - 在 ML 中导出类型表达式

types - SML : Inputting an empty list into function gives error “Warning: type vars not generalized because of value restriction…”

binary-tree - 标准 ML 二叉树遍历

windows - 在 Windows 上运行标准机器学习

c++ - C++ 中的数据抽象和二进制方法

syntax - 是否有函数式编程语言具有用于更改对象部分的语法糖?