为什么更喜欢在OCaml中使用curry to tuple参数?

时间:2012-05-19 16:20:21

标签: ocaml tuples currying

"Introduction to Caml"

  

注意,在Caml中,最好对多参数函数使用Curried函数定义,而不是元组。

'a -> 'b -> 'c调用约定与'a * 'b -> 'c进行比较。

当使用SML / NJ时,我习惯于为输入和输出使用元组类型:('a * 'b) -> ('c * 'd)所以使用元组表示多个输入似乎与我表达多个输出的方式是对称的。

为什么curous推荐用于OCaml函数声明而不是元组参数?是否允许进行currying / partial评估会带来更大的灵活性,还是从OCaml编译器的实现细节中获得了一些其他好处?

3 个答案:

答案 0 :(得分:6)

我认为很多是惯例 - OCaml中的标准库函数是curry,而在Standard ML中它们通常不是除了一些高阶函数。但是,语言中存在一个区别:运算符(例如(*))在OCaml中被curry(例如int -> int -> int);而它们在标准ML中没有结果(例如op*可以是(int * int) -> int)。因此,内置的高阶函数(例如折叠)也采用在OCaml中进行干扰并在标准ML中不受影响的函数;这意味着你的函数可以使用它,你需要遵循相应的约定,然后从那里开始。

答案 1 :(得分:3)

是的,这主要是标志性的便利性和部分应用的灵活性。在OCaml中,Curried函数是惯用的,编译器可能比tupled函数更好地优化它们(而SML编译器通常优化元组)。

tupling的优点是你提到的参数/结果对称性(在编写函数时特别有用),也许是符号熟悉度(至少对于来自非功能世界的人来说)。

答案 2 :(得分:1)

关于OCaml优化的一些评论。

在OCaml中,我注意到在将它们作为参数传递时总是会分配元组。即使主堆中的分配在ocaml中速度很快,它当然比什么都不做要长。因此,每次将元组作为参数传递时,都会花费一些时间来分配和填充元组。

我预计ocaml编译器会优化不需要构建元组的情况。例如,当您内联被调用函数时,您可能只使用元组组件而不是元组本身。因此,元组可以被忽略。不幸的是,在这种情况下,OCaml不会删除无用的元组并仍然执行分配。因此,在代码的关键部分使用元组可能不是一个好主意。