私は講義 2.2 高階関数 ( Scala の関数型プログラミングの原則) を見ていました。そこで、sum 関数は次のように定義されます。
def sum(f: Int => Int, a: Int, b: Int) { ... }
後で、同じ関数が次のように定義されます。
def sum(f: Int => Int)(a: Int, b: Int) { ... }
それらは同等のように見えますが、なぜ選択するのかについての説明はありません。
私は講義 2.2 高階関数 ( Scala の関数型プログラミングの原則) を見ていました。そこで、sum 関数は次のように定義されます。
def sum(f: Int => Int, a: Int, b: Int) { ... }
後で、同じ関数が次のように定義されます。
def sum(f: Int => Int)(a: Int, b: Int) { ... }
それらは同等のように見えますが、なぜ選択するのかについての説明はありません。
2番目の定義は、2つの引数リストを持つメソッドを宣言します。暗黙を無視すると、これは通常、カリー化された関数アプリケーションを有効にするために使用されます。基本的な考え方は、関数のいくつかのパラメーターをバインドできることです。これにより、残りの引数が少ない別の関数、つまりまだバインドされていない関数が生成されます。簡単な教科書の例を次に示します。
def add(xs: List[Int])(y: Int) =
xs.map(_ + y)
// Bind first argument and store resulting function in f
val f = add(List(2,3,5,7,11))_
println(f(0)) // List(2, 3, 5, 7, 11)
println(f(10)) // List(12, 13, 15, 17, 21)
// Bind first argument and store resulting function in g
val g = add(List(0,1,0,1,0,1))_
println(g(1)) // List(1, 2, 1, 2, 1, 2)
println(g(-1)) // List(-1, 0, -1, 0, -1, 0)
// Regular invocation
println(add(List(1,2,3))(4)) // List(5, 6, 7)
オンラインでのカリー化に関する記事はたくさんあります。たとえば、 Scalaでのカリー化の使用方法や、Scalaでのカリー化には複数の方法があります。
オーバーオーバーから1つを選択する理由について:Haskellでは、基本的に、カレーなしバージョンよりもカレーバージョンを選択します。後者はパラメーターを部分的にバインドできるという利点があり、「構文ペナルティ」や実行時ペナルティがないためです。カレーバージョンを使用するため。これはScalaには当てはまらないので(構文に関しては上記のコードスニペットからわかるように)、メソッド/関数の最も可能性の高いユースケースが役立つことがわかっている場合を除いて、カリー化されていないスタイルを好むかもしれません。カリー化から。
ある種ですが、正確ではありません。最大の違いは、複数のパラメーターリストを使用すると、すべてのパラメーターを指定しなくても、関数をより簡単に使用できることです。
例として、次のように2つの関数を定義しましょう。
def sum1(f: Int => Int, a: Int, b: Int) = f(a + b)
def sum2(f: Int => Int)(a: Int, b: Int) = f(a + b)
次に、パラメータとして2つのsg
を取り、を生成する別の関数を受け取る関数を定義しましょう。Int
Int
def g(f: (Int, Int) => Int) = f(3, 5)
sum
複数のパラメーターリストを含むバージョンでは、最初のリストのパラメーターを指定してから、この部分的に適用された関数をg
次のように渡すことができます。
g(sum2(_ + 1))
これはとてもシンプルでとてもきれいです。
のように個別のパラメーターリストがない場合はsum1
、ラムダ式を記述して、パラメーターの出所を示す必要がa
ありb
ます。
g((a: Int, b: Int) => sum1(_ + 1, a, b))