Consider a function that returns another function:
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
}
The idea here is: An outer function does some heavy processing and returns a inner function that uses variables defined in the enclosing scope:
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)
Note that the outer function is evaluated only once.
With multiple parameter lists and Scala's Currying syntax we can write something similar:
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)
}
But the "outer" function gets evaluated every time:
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)
My question is, can I somehow force prepareCurried
to be evaluated on the line bellow?
val doSomethingWithOtherArgs = prepareCurried(List(4, 5, 6)) _
To put it differently, is it possible to get the same effect as "evaluation on definition" when partially applying a function with multiple parameter lists?