80

複数のパラメーター リスト (例: リストdef foo(a:Int)(b:Int) = {}ごとの複数のパラメーター) はdef foo(a:Int, b:Int) = {}、私が知る限り、意味的に同等であり、ほとんどの関数型言語には、複数のパラメーター (F# など) を宣言する方法が 1 つしかありません。

これら両方のスタイルの関数定義をサポートする唯一の理由は、パラメーターを 1 つしか持たないパラメーター リストを使用して、構文に似た言語拡張を許可するためです。

def withBufferedWriter(file: File)(block: BufferedWriter => Unit)

構文のように呼び出すことができるようになりました

withBufferedWriter(new File("myfile.txt")) { out =>
  out write "whatever"
  ...
}

ただし、複数のパラメーター リストを使用せずに中括弧の使用をサポートする方法は他にもあります。

関連する質問: Scala で複数のパラメーター リストを使用することを「カリー化」と呼ぶのはなぜですか? カリー化は通常、部分適用をサポートするために n 項関数を単項にする手法として定義されます。ただし、Scala では、関数の「カリー化された」(それぞれ 1 つのパラメーターを持つ複数のパラメーター リスト) バージョンを作成せずに、関数を部分的に適用できます。

4

5 に答える 5

78

たとえば、次のことが可能になります。

scala> def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
foo: (as: Int*)(bs: Int*)(cs: Int*)Int

scala> foo(1, 2, 3)(4, 5, 6, 7, 9)(10, 11)
res7: Int = 3906
于 2011-01-13T19:55:43.067 に答える
49

言語の一部のように見えるメソッドを記述できるようにするだけでなく (既に見つけました)、型推論器が一度に 1 つのブロックで動作することに注意してください。

だからこれで:

def foo[T](a: T, b: T)(op: (T,T)=>T) = op(a,b)
foo(1,2){_+_}

Tは最初に として推論されInt、次にクロージャー内の 2 つのアンダースコアの型として使用されます。これにより、コンパイラは + 操作が有効であることを完全なタイプ セーフで認識します。

于 2011-01-14T00:36:01.140 に答える
29

「関連する質問」に答えるために、カリー化は、たとえば(A, B, C) => D、複数の引数の関数を、1 つの引数を取り、関数を返す関数に変換する単純な方法ですA => (B => (C => D))(括弧は示されていますが、必須ではありません)。

タプル化された形式とカリー化された形式は同形であり、それらの間で自由に変換できます。これらはすべて同等ですが、構文上の意味が異なります。

(A, B, C, D, E) => F
((A, B), (C, D, E)) => F
(A, B) => (C, D, E) => F

個別のパラメーター グループを宣言するとき、これはあなたが行っている一種のカリー化です。multi-parameter-group メソッドは、関数を返すメソッドです...これは REPL で確認できます。

scala> def foo(a:Int, b:Int)(c:Int, d:Int, e:Int):Int = 9
foo: (a: Int,b: Int)(c: Int,d: Int,e: Int)Int

scala> foo _                                             
res4: (Int, Int) => (Int, Int, Int) => Int = <function2>
于 2011-01-13T21:36:01.173 に答える
22

デフォルト引数の後方参照:

case class Foo(bar: Int)

def test(f: Foo)(i: Int = f.bar) = i*i

test(Foo(3))()
于 2013-02-27T20:22:33.927 に答える
15

動機の1つが暗黙のパラメータリストであったことを私は知っています。「暗黙的」はリストのプロパティであり、パラメータではありません。もう1つは、おそらくケースクラスでした。最初のパラメータリストのみがケースフィールドになります。

于 2011-01-14T05:36:25.447 に答える