为什么 Scala 既提供多个参数列表又提供每个列表多个参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4684185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Scala provide both multiple parameters lists and multiple parameters per list?
提问by Yuvi Masory
Multiple parameters lists, e.g. def foo(a:Int)(b:Int) = {}and multiple parameters per list, e.g. def foo(a:Int, b:Int) = {}are semantically equivalent so far as I can tell, and most functional languages have only one way of declaring multiple parameters, e.g. F#.
多个参数列表,例如def foo(a:Int)(b:Int) = {}和每个列表的多个参数,def foo(a:Int, b:Int) = {}就我所知,例如在语义上是等效的,并且大多数函数式语言只有一种声明多个参数的方法,例如 F#。
The only reason I can figure out for supporting both these styles of function definitions is to allow syntax-like language extensions using a parameter list that has only one parameter in it.
我认为支持这两种函数定义风格的唯一原因是允许使用只有一个参数的参数列表进行类似语法的语言扩展。
def withBufferedWriter(file: File)(block: BufferedWriter => Unit)
can now be called with the syntax-looking
现在可以使用语法外观调用
withBufferedWriter(new File("myfile.txt")) { out =>
out write "whatever"
...
}
However, there could be other ways of supporting the use of curly braces without having multiple parameter lists.
但是,可能还有其他方法支持使用大括号而无需多个参数列表。
A related question: why is the use of multiple parameter lists in Scala called "currying"? Currying is usually defined as a technique for making an n-ary function unary for the sake of supporting partial application. However, in Scala one can partially apply a function without making a "curried" (multiple parameter lists with one param each) version of the function.
一个相关的问题:为什么在 Scala 中使用多个参数列表称为“currying”?柯里化通常被定义为一种为了支持部分应用而使 n 元函数成为一元函数的技术。但是,在 Scala 中,可以部分应用一个函数,而无需制作该函数的“柯里化”(多个参数列表,每个列表一个参数)版本。
采纳答案by Knut Arne Vedaa
It makes you able to do e.g.:
它使您能够执行以下操作,例如:
scala> def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
foo: (as: Int*)(bs: Int*)(cs: Int*)Int
scala> foo(1, 2, 3)(4, 5, 6, 7, 9)(10, 11)
res7: Int = 3906
回答by Kevin Wright
As well as allowing you to write methods that look like part of the language (which you already spotted), it's worth noting that the type inferencer will work with one block at a time.
除了允许您编写看起来像语言的一部分的方法(您已经发现)之外,值得注意的是类型推断器将一次处理一个块。
So in this:
所以在这个:
def foo[T](a: T, b: T)(op: (T,T)=>T) = op(a,b)
foo(1,2){_+_}
Twill first be inferred as Int, which will then be used as the type of the two underscores in the closure.
This is how the compiler then knows, with complete type safety, that the + operation is valid.
T将首先推断为Int,然后将其用作闭包中两个下划线的类型。这就是编译器如何在完全类型安全的情况下知道 + 操作是有效的。
回答by Tom Crockett
To answer your "related question," currying is simply a way of turning a function of multiple arguments, for example (A, B, C) => D, into a function which takes one argument and returns a function, e.g. A => (B => (C => D))(parentheses shown but not necessary).
为了回答您的“相关问题”,柯里化只是一种将具有多个参数的函数(例如(A, B, C) => D)转换为一个接受一个参数并返回一个函数的函数的方法,例如A => (B => (C => D))(括号显示但不是必需的)。
The tuple-ized form and the curried form are isomorphic, and we may translate freely between them. All of these are equivalent, but have different syntactic implications:
元组化形式和柯里化形式是同构的,我们可以在它们之间自由转换。所有这些都是等价的,但具有不同的句法含义:
(A, B, C, D, E) => F
((A, B), (C, D, E)) => F
(A, B) => (C, D, E) => F
When you declare separate parameter groups, this is the kind of currying you're doing. The multi-parameter-group method is a method which returns a function... you can see this in the REPL:
当您声明单独的参数组时,这就是您正在做的那种柯里化。多参数组方法是一种返回函数的方法……您可以在 REPL 中看到这一点:
scala> def foo(a:Int, b:Int)(c:Int, d:Int, e:Int):Int = 9
foo: (a: Int,b: Int)(c: Int,d: Int,e: Int)Int
scala> foo _
res4: (Int, Int) => (Int, Int, Int) => Int = <function2>
回答by 0__
Back references in default arguments:
默认参数中的反向引用:
case class Foo(bar: Int)
def test(f: Foo)(i: Int = f.bar) = i*i
test(Foo(3))()
回答by psp
I know one of the motivations was implicit parameter lists. "implicit" is a property of the list, not the parameter. Another was probably case classes: only the first parameter list become case fields.
我知道动机之一是隐式参数列表。“隐式”是列表的属性,而不是参数。另一个可能是案例类:只有第一个参数列表成为案例字段。

