多个参数列表,例如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"(多个参数列表,每个参数列表).
我试图了解在Scala中讨论部分应用程序的优点.请考虑以下代码:
def sum(f: Int => Int) = (a: Int, b: Int) => f(a) + f(b)
def sum2(f: Int => Int, a: Int, b: Int): Int = f(a) + f(b)
def sum3(f: Int => Int)(a: Int, b: Int): Int = f(a) + f(b)
val ho = sum({identity})
val partial = sum2({ identity }, _, _)
val currying = sum3({ identity })
val a = currying(2, 2)
val b = partial(2, 2)
val c = ho(2, 2)
Run Code Online (Sandbox Code Playgroud)
那么,如果我可以轻松计算部分应用的功能,那么currying的优点是什么?
我是Scala的新手,我正在使用2.9.1,而我正试图了解如何使用部分功能.我对curried函数有一个基本的了解,我知道部分函数有点像curried函数,它们只有2nary或者其他类似函数.你可以告诉我,我有点绿.
看起来在某些情况下,比如XML过滤,能够部分功能是非常有利的,所以我希望能更好地理解如何使用它们.
我有一个使用RewriteRule结构的函数,但我需要它使用两个参数,而RewriteRule结构只需要一个,或一个部分函数.我认为这是我认为它有用的案例之一.
任何建议,链接,智慧的话等欢迎!
到目前为止,答案非常好,并且澄清了我的一些基本误解.我认为他们也解释了我在哪里挣扎 - 我想也许发布一个更具体的新问题会有所帮助,所以我也会这样做.
我在这里看一看:Scala currying与部分应用的函数,但那里的答案更多地回答了Scala中currying,partial application和normal函数之间的功能和语义差异.
我有兴趣了解这些可用于功能的不同技术之间是否有任何性能考虑因素,即......
如果我们使用普通函数的性能作为基础:
def add3(a: Int, b: Int, c: Int) = a + b + c
add3(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
然后比较:
// First
(add3 _).curried(1)(2)(3)
// Second
val add2 = add3(1, _: Int, _: Int)
val add1 = add2(2, _: Int)
add1(3)
// Third
def add3(a: Int)(b: Int)(c: Int) = a + b + c
add3(1)(2)(3)
Run Code Online (Sandbox Code Playgroud)
如果我发现一些性能不佳的代码(无论是在速度还是内存使用方面),我可能想要注意的是什么?我看到在所述代码段中发生了很多currying或部分应用程序?
例如,在Haskell中,我会查看正在生成多少个thunk并在其中闲逛.我认为Scala使用类似的方法来传递部分应用和curried函数,而Scala如何处理这些事情的细节将是很有价值的.
这些代码中这些下划线用法之间有什么区别和术语名称:(参见handler(resource)部分)
1.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): T = {
val resource = new java.io.FileInputStream(f)
try {
val hh = handler(resource)_
hh(2)
} finally {
resource.close()
}
}
val bs = new Array[Byte](4)
readFile(new File("scala.txt")) {
input => b: Byte => println("Read: " + (input.read(bs) + b))
}
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:
Error:(55, 29) _ must follow method; cannot follow Byte => T
val hh = handler(resource)_
^
Run Code Online (Sandbox Code Playgroud)
这是什么意思?
2.
def readFile[T](f: File)(handler: FileInputStream => Byte => T): …Run Code Online (Sandbox Code Playgroud) 特定
scala> def method(x: Int) = x
method: (x: Int)Int
scala> val func = (x: Int) => x
func: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)
请考虑以下代码:
scala> method _
res0: Int => Int = <function1>
scala> func(_)
res1: Int => Int = <function1>
scala> func _
res2: () => Int => Int = <function0>
Run Code Online (Sandbox Code Playgroud)
我可以理解,这res0是eta扩展,res1相当于lambda函数(x) => func(x).但我无法弄清楚输出res2.谁有人可以帮我解释一下?
我正在使用默认值构造函数创建一个case类:
abstract class Interaction extends Action
case class Visit(val url: String)(val timer: Boolean = false) extends Interaction
Run Code Online (Sandbox Code Playgroud)
但是,例如,如果不使用其所有参数,我就无法创建任何实例.如果我写:
Visit("https://www.linkedin.com/")
Run Code Online (Sandbox Code Playgroud)
编译器会抱怨:
missing arguments for method apply in object Visit;
follow this method with `_' if you want to treat it as a partially applied function
[ERROR] Visit("http://www.google.com")
Run Code Online (Sandbox Code Playgroud)
我需要做些什么来解决它?
我找到了一些关于什么是咖喱以及它能做些什么的好帖子.它可以将带有参数列表的函数转换为函数列表.我不清楚它在什么情况下是有用的.谁能给我一个具体的例子?