Власне кажучи, це не функція, що працює, а метод із декількома списками аргументів, хоча, правда, це виглядає як функція.
Як ви вже сказали, декілька списків аргументів дозволяють використовувати метод замість частково застосованої функції. (Вибачте за загально дурні приклади, які я використовую)
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(_))
Ще одна перевага полягає в тому, що ви можете використовувати фігурні дужки замість дужок, що виглядає добре, якщо другий список аргументів складається з однієї функції або функції. Напр
NonCurr.tabulate(10, { i => val j = util.Random.nextInt(i + 1); i - i % 2 })
проти
IndexedSeq.tabulate(10) { i =>
val j = util.Random.nextInt(i + 1)
i - i % 2
}
Або для думки:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
Ще однією перевагою є те, що ви можете посилатися на аргументи попереднього списку аргументів для визначення значень аргументів за замовчуванням (хоча ви також можете сказати, що це недолік, що ви не можете цього робити в одному списку :)
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
Нарешті, у відповіді на відповідне повідомлення є ще три додатки. Чому Scala надає як кілька списків параметрів, так і декілька параметрів у списку? . Я просто скопіюю їх тут, але заслуга належить Кнуту Арне Ведаа, Кевіну Райту та extempore.
По-перше: ви можете мати кілька аргументів var:
def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
... що не було б можливим в одному списку аргументів.
По-друге, це допомагає висновку типу:
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, _ + _)
І нарешті, це єдиний спосіб, яким ви можете мати неявні та неявні аргументи, як implicit
це модифікатор для цілого списку аргументів:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ???
def gaga2[A](x: A, implicit mf: Manifest[A]) = ???