4

我(从一本 SML 书中)了解到,SML 中的函数总是只需要一个参数:一个元组。一个接受多个参数的函数只是一个接受一个元组作为参数的函数,在函数绑定中通过一个元组绑定来实现。我明白这一点。

但是在这之后,这本书说了一些我不明白的东西:

this point makes SML language flexible and elegant design, and you can do something useful that you cannot do in Java.

为什么这种设计使语言灵活?文本指的是什么,SML可以但java不能?

4

2 回答 2

6

使用元组而不是多个参数增加了灵活性,因为高阶函数可以与任何“arity”的函数一起使用。例如,要创建 list [f x, f y, f z],您可以像这样使用高阶函数map

map f [x, y, z]

这很容易——你可以用任何语言做到这一点。但是现在让我们考虑f实际需要两个参数的情况。如果f是一个真正的二元函数(假设 SML 有这样的函数),我们需要一个不同的版本map,可以使用二元函数而不是一元函数(如果我们想使用三元函数,我们会也需要一个版本)。但是使用元组我们可以这样写:

map f [(x,a), (y,b), (z,c)]

这将创建列表[f (x,a), f (y,b), f (z,c)]

PS:在 SML 中,所有需要多个参数的函数都采用元组并不是真的。通常函数使用柯里化而不是元组来表示多个参数,但我想你的书还没有柯里化。柯里化函数不能以与上述相同的方式使用,因此在这个意义上它们并不通用。

于 2013-01-28T00:42:16.797 回答
3

实际上,我认为您根本不了解这一点。

首先,SML 中的函数不接受元组作为参数,它们可以接受任何东西作为参数。有时使用元组作为传递多个参数的方法很方便。例如,一个函数可以将记录作为参数、整数、字符串,甚至可以将另一个函数作为参数。也可以说它可以“无参数”,因为它可以将单位作为参数。

如果我正确理解您关于采用“多个参数”的函数的说法,那么您就是在谈论currying。例如

fun add x y = x + y

在 SML 中,柯里化被实现为派生形式(句法糖)。有关其实际工作原理的详细说明,请参阅此答案。总之,SML 中只有匿名函数,但是我们可以将它们绑定到名称,以便以后可以“引用”/使用它们。

看哪,乱七八糟的要开始了。

在谈论任何事情的灵活性之前,我认为这是为了说明我的想法。我非常喜欢这种对编程语言灵活性的定义:“ [...] 语言中的发音可以使用出乎意料的多种方式

在 SML 的情况下,选择了一种小而简单的核心语言。这使得实现编译器和解释器变得容易。灵活性体现在 SML 语言的许多特性已经使用这些核心语言特性来实现,例如匿名函数、模式匹配和 SML 具有高阶函数的事实。
这方面的例子有柯里化、case 表达式、记录选择器、if-the-else 表达式、表达式序列。

我想说这使得 SML 核心语言非常灵活,坦率地说非常优雅。

关于 SML 可以做什么,Java 不能(在这种情况下),我不太确定作者的去向。但是我很确定作者可能有点偏颇,因为您也可以在 java 中做任何事情。然而,它可能需要大量的编码:)

于 2013-01-28T01:05:05.560 回答