【发布时间】:2017-07-11 06:01:22
【问题描述】:
考虑一个返回另一个函数的函数:
def prepareFunction(args: List[Any]): String => Unit = {
println(s"Slow processing of $args...")
val results = args.map(a => s"processed $a")
def doSomething(s: String): Unit = {
println(s"Do something quick with $s and $results")
}
doSomething
}
这里的想法是:一个外部函数进行一些繁重的处理并返回一个使用在封闭范围中定义的变量的内部函数:
val doSomethingWithArgs = prepareFunction(List("arg1", "arg2", 3))
//> Slow processing of List(arg1, arg2, 3)...
doSomethingWithArgs("abc")
//> Do something quick with abc and List(processed arg1, processed arg2, processed 3)
doSomethingWithArgs("cde")
//> Do something quick with cde and List(processed arg1, processed arg2, processed 3)
请注意,外部函数只计算一次。
使用多个参数列表和 Scala 的 Currying syntax 我们可以编写类似的内容:
def prepareCurried(args: List[Any])(s: String): Unit = {
println(s"Slow processing of $args")
val results = args.map(a => s"processed $a")
def doSomething(s: String): Unit = {
println(s"Do something quick with $s and $results")
}
doSomething(s)
}
但“外部”函数每次都会被评估:
val doSomethingWithOtherArgs = prepareCurried(List(4, 5, 6)) _
doSomethingWithOtherArgs("abc")
//> Slow processing of List(4, 5, 6)
//> Do something quick with abc and List(processed 4, processed 5, processed 6)
doSomethingWithOtherArgs("cde")
//> Slow processing of List(4, 5, 6)
//> Do something quick with cde and List(processed 4, processed 5, processed 6)
我的问题是,我可以以某种方式强制prepareCurried 在下面的行中进行评估吗?
val doSomethingWithOtherArgs = prepareCurried(List(4, 5, 6)) _
换句话说,在部分应用具有多个参数列表的函数时,是否可以获得与"evaluation on definition"相同的效果?
【问题讨论】:
-
这就是柯里化函数的定义应该如何表现,我想不出你为什么要改变它的任何理由。您的模式 1 中已经有其他选择。
-
嘿@Sarvesh,没有什么特别的原因,我只是想知道currying和返回函数的函数之间的对称性。