Строго говоря, это не карри функция, а метод с несколькими списками аргументов, хотя по общему признанию он выглядит как функция.
Как вы сказали, списки с несколькими аргументами позволяют использовать метод вместо частично прикладной функции.(Извините за обычно глупые примеры, которые я использую)
object NonCurr {
def tabulate[A](n: Int, fun: Int => A) = IndexedSeq.tabulate(n)(fun)
}
NonCurr.tabulate[Double](10, _) // not possible
val x = IndexedSeq.tabulate[Double](10) _ // possible. x is Function1 now
x(math.exp(_)) // complete the application
Еще одним преимуществом является то, что вы можете использовать фигурные скобки вместо скобок, что выглядит хорошо, если список второго аргумента состоит из одной функции или thunk.Например,
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
}
Или для thunk:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
Другое преимущество состоит в том, что вы можете ссылаться на аргументы из предыдущего списка аргументов для определениязначения аргументов по умолчанию (хотя можно также сказать, что недостатком является то, что вы не можете сделать это в одном списке:)
// again I'm not very creative with the example, so forgive me
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){_ + _} // compiler can infer the type of the op function
def foo2[T](a: T, b: T, op: (T,T) => T) = op(a, b)
foo2(1, 2, _ + _) // compiler too stupid, unfortunately
И, наконец, это единственный способ, которым вы можете иметь неявные и неявные аргументы,implicit
является модификатором для всего списка аргументов:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ??? // ok
def gaga2[A](x: A, implicit mf: Manifest[A]) = ??? // not possible
.