0

私は講義 2.2 高階関数 ( Scala の関数型プログラミングの原則) を見ていました。そこで、sum 関数は次のように定義されます。

def sum(f: Int => Int, a: Int, b: Int) { ... }

後で、同じ関数が次のように定義されます。

def sum(f: Int => Int)(a: Int, b: Int) { ... }

それらは同等のように見えますが、なぜ選択するのかについての説明はありません。

4

2 に答える 2

2

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には当てはまらないので(構文に関しては上記のコードスニペットからわかるように)、メソッド/関数の最も可能性の高いユースケースが役立つことがわかっている場合を除いて、カリー化されていないスタイルを好むかもしれません。カリー化から

于 2012-09-27T08:07:24.297 に答える
1

ある種ですが、正確ではありません。最大の違いは、複数のパラメーターリストを使用すると、すべてのパラメーターを指定しなくても、関数をより簡単に使用できることです。

例として、次のように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を取り、を生成する別の関数を受け取る関数を定義しましょう。IntInt

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))
于 2012-09-27T08:07:51.300 に答える