Yuv*_*ory 78 scala currying partial-application
多个参数列表,例如def foo(a:Int)(b:Int) = {}
每个列表的多个参数,例如def foo(a:Int, b:Int) = {}
,就我所知,在语义上是等效的,并且大多数函数语言只有一种方式来声明多个参数,例如F#.
我可以找到支持这两种函数定义样式的唯一原因是允许使用只有一个参数的参数列表进行类似语法的语言扩展.
def withBufferedWriter(file: File)(block: BufferedWriter => Unit)
Run Code Online (Sandbox Code Playgroud)
现在可以使用syntax-looking调用
withBufferedWriter(new File("myfile.txt")) { out =>
out write "whatever"
...
}
Run Code Online (Sandbox Code Playgroud)
但是,如果没有多个参数列表,可能还有其他方法可以支持花括号的使用.
一个相关的问题:为什么在Scala中使用多个参数列表称为"currying"?Currying通常被定义为为了支持部分应用而使n-ary函数一元化的技术.但是,在Scala中,可以部分应用函数,而不会使函数的"curried"(多个参数列表,每个参数列表).
Knu*_*daa 76
它使你能够做到:
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
Run Code Online (Sandbox Code Playgroud)
Kev*_*ght 45
除了允许您编写看起来像语言的一部分的方法(您已经发现),值得注意的是类型推理器一次只能处理一个块.
所以在这:
def foo[T](a: T, b: T)(op: (T,T)=>T) = op(a,b)
foo(1,2){_+_}
Run Code Online (Sandbox Code Playgroud)
T
首先将推断为Int
,然后将其用作闭包中两个下划线的类型.这就是编译器在完全类型安全的情况下知道+操作有效的方式.
Tom*_*ett 24
为了回答你的"相关问题",currying只是一种将多个参数(A, B, C) => D
的函数转换为一个函数,它接受一个参数并返回一个函数,例如A => (B => (C => D))
(括号显示但不必要).
元组化形式和咖喱形式是同构的,我们可以在它们之间自由翻译.所有这些都是等价的,但具有不同的句法含义:
(A, B, C, D, E) => F
((A, B), (C, D, E)) => F
(A, B) => (C, D, E) => F
Run Code Online (Sandbox Code Playgroud)
当你声明单独的参数组时,这就是你正在做的那种.multi-parameter-group方法是一个返回函数的方法......你可以在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>
Run Code Online (Sandbox Code Playgroud)
0__*_*0__ 22
默认参数中的返回引用:
case class Foo(bar: Int)
def test(f: Foo)(i: Int = f.bar) = i*i
test(Foo(3))()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25538 次 |
最近记录: |