複数のパラメータリストメソッド
型推論の場合
複数のパラメーターセクションを持つメソッドを使用して、最初のセクションのパラメーターを使用して、後続のセクションの引数に期待される型を提供する型引数を推論することにより、ローカル型の推論を支援できます。foldLeft
標準ライブラリには、これの標準的な例があります。
def foldLeft[B](z: B)(op: (B, A) => B): B
List("").foldLeft(0)(_ + _.length)
これが次のように書かれている場合:
def foldLeft[B](z: B, op: (B, A) => B): B
より明示的なタイプを提供する必要があります。
List("").foldLeft(0, (b: Int, a: String) => a + b.length)
List("").foldLeft[Int](0, _ + _.length)
流暢なAPIの場合
複数のパラメーターセクションメソッドのもう1つの用途は、言語構造のように見えるAPIを作成することです。呼び出し元は、括弧の代わりに中括弧を使用できます。
def loop[A](n: Int)(body: => A): Unit = (0 until n) foreach (n => body)
loop(2) {
println("hello!")
}
N個の引数リストをM個のパラメーターセクションを持つメソッドに適用すると、N <Mは、明示的に_
、または暗黙的に、期待されるタイプの関数に変換できます。FunctionN[..]
。を使用。これは安全機能です。背景については、ScalaリファレンスのScala2.0の変更ノートを参照してください。
カレー関数
カレー関数(または単に関数を返す関数)は、N個の引数リストに簡単に適用できます。
val f = (a: Int) => (b: Int) => (c: Int) => a + b + c
val g = f(1)(2)
このマイナーな便利さは時々価値があります。ただし、関数は型パラメトリックにすることはできないため、場合によってはメソッドが必要になることに注意してください。
2番目の例はハイブリッドです。関数を返す1パラメーターセクションメソッドです。
多段階計算
カレー関数は他にどこで役に立ちますか?これがいつも出てくるパターンです:
def v(t: Double, k: Double): Double = {
val ft = f(t)
g(ft, k)
}
v(1, 1); v(1, 2);
結果をどのように共有できf(t)
ますか?一般的な解決策は、ベクトル化されたバージョンを提供することですv
。
def v(t: Double, ks: Seq[Double]: Seq[Double] = {
val ft = f(t)
ks map {k => g(ft, k)}
}
醜い!関係のない懸念を絡ませました-g(f(t), k)
のシーケンスの計算とマッピングks
。
val v = { (t: Double) =>
val ft = f(t)
(k: Double) => g(ft, k)
}
val t = 1
val ks = Seq(1, 2)
val vs = ks map (v(t))
関数を返すメソッドを使用することもできます。この場合、もう少し読みやすくなります。
def v(t:Double): Double => Double = {
val ft = f(t)
(k: Double) => g(ft, k)
}
しかし、複数のパラメーターセクションを持つメソッドで同じことを行おうとすると、行き詰まります。
def v(t: Double)(k: Double): Double = {
^
`-- Can't insert computation here!
}