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

amn*_*amn 3 ml

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

fun f x y;
Run Code Online (Sandbox Code Playgroud)

fun f (x, y);
Run Code Online (Sandbox Code Playgroud)

据我所知,第一个采用两个参数,而第二个采用元组.如果是这样的话,那么使用一个与另一个相比有什么(实际)含义?一个论证哪个是最好的风格?假设,实际上并不需要将元组作为整体使用,即仅仅xy单独使用元组.

new*_*cct 5

是的,正如你所说,第一个采用"两个参数",而第二个采用一个参数是一个元组.但是,要了解真正发生的事情,你必须了解currying.在ML中,每个"函数"只需要一个参数(不多也不少).

在第二种情况下,这很容易理解,它需要一个参数,它是一个元组,它对元组中的事物做了一些事情,并返回一个结果.在第一种情况下,您定义一个带有一个参数的函数,然后返回一个带有另一个参数的函数,然后返回结果.

比方说,这是一个需要两个ints并返回一个的函数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拿a int,返回一个然后应用到另一个int的函数.这是currying的要点.ML的语法只是让它变得透明.

咖喱版(第一版)允许您进行部分应用.这意味着,虽然你的函数在概念上有两个参数,但你不必给它那么多参数.所以f 3 4我们上面(也就是说(f 3) 4),如果我们只是采用了它f 3,而不仅仅是应用它4,只需保留它并将其存储在变量或其他东西中?通过"赋予函数少于它想要的参数",我们自动获得一个带有剩余参数的函数.例如,我们可以这样做map (f 3) someList,它将计算列表中f 3 x每个x列表,而无需编写一些复杂的语法.

在标准ML中,库函数大多数是未经处理的形式; 而在OCaml和Haskell,他们大多是以咖喱形式.(请参阅此问题.)但是,高阶函数(如map和fold)的SML库函数倾向于将它们的函数参数放在一个单独的(curried)参数中.