Estrictamente hablando, esta no es una función curry, sino un método con múltiples listas de argumentos, aunque ciertamente parece una función.
Como dijiste, las listas de argumentos múltiples permiten que el método se use en lugar de una función aplicada parcialmente. (Perdón por los ejemplos generalmente tontos que uso)
object NonCurr {
def tabulate[A](n: Int, fun: Int => A) = IndexedSeq.tabulate(n)(fun)
}
NonCurr.tabulate[Double](10, _)
val x = IndexedSeq.tabulate[Double](10) _
x(math.exp(_))
Otro beneficio es que puede usar llaves en lugar de paréntesis, lo que se ve bien si la segunda lista de argumentos consiste en una sola función o procesador. P.ej
NonCurr.tabulate(10, { i => val j = util.Random.nextInt(i + 1); i - i % 2 })
versus
IndexedSeq.tabulate(10) { i =>
val j = util.Random.nextInt(i + 1)
i - i % 2
}
O para el thunk:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
Otra ventaja es que puede consultar los argumentos de una lista de argumentos anterior para definir valores de argumento predeterminados (aunque también podría decir que es una desventaja que no puede hacer eso en una lista única :)
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
Finalmente, hay otras tres aplicaciones en una respuesta a una publicación relacionada. ¿Por qué Scala proporciona listas de parámetros múltiples y parámetros múltiples por lista? . Los copiaré aquí, pero el mérito es de Knut Arne Vedaa, Kevin Wright y extempore.
Primero: puede tener varios argumentos var:
def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
... que no sería posible en una sola lista de argumentos.
En segundo lugar, ayuda a la inferencia de tipos:
def foo[T](a: T, b: T)(op: (T,T) => T) = op(a, b)
foo(1, 2){_ + _}
def foo2[T](a: T, b: T, op: (T,T) => T) = op(a, b)
foo2(1, 2, _ + _)
Y por último, esta es la única forma en que puede tener implicit
argumentos implícitos y no implícitos, al igual que un modificador para una lista completa de argumentos:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ???
def gaga2[A](x: A, implicit mf: Manifest[A]) = ???