厳密に言えば、これはカリー化された関数ではなく、複数の引数リストを持つメソッドですが、確かに関数のように見えます。
あなたが言ったように、複数の引数リストにより、部分的に適用された関数の代わりにメソッドを使用できます。(私が使用する一般的にばかげた例で申し訳ありません)
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
もう 1 つの利点は、2 番目の引数リストが単一の関数またはサンクで構成されている場合に見栄えのする括弧の代わりに中括弧を使用できることです。例えば
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)
}
もう1つの利点は、デフォルトの引数値を定義するために以前の引数リストの引数を参照できることです(ただし、単一のリストでそれを行うことができないという欠点とも言えます:)
// again I'm not very creative with the example, so forgive me
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
最後に、関連する投稿への回答に他の 3 つのアプリケーションがあります。. ここにそれらをコピーするだけですが、功績は Knut Arne Vedaa、Kevin Wright、および 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