追加 - scala vector




なぜScalaは複数のパラメータリストとリストごとに複数のパラメータを提供しますか? (4)

あなたの "関連する質問"に答えるために、カリングは、例えば(A, B, C) => Dような複数の引数の関数を一つの引数をとり、関数を返す関数に単純に変換する方法です。例えばA => (B => (C => D)) (カッコが表示されますが、必要はありません)。

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

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

別々のパラメータグループを宣言すると、これはカリングの種類です。 マルチパラメータグループメソッドは、関数を返すメソッドです...これは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>

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

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

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

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

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

しかし、複数のパラメータリストを持たなくても中括弧の使用をサポートする他の方法があるかもしれません。

関連する質問:スカラの複数のパラメータリストを「カリング」と呼ぶ理由は何ですか? カリングは、通常、部分的なアプリケーションをサポートするために、n進関数を単項式にするためのテクニックとして定義されます。 しかし、Scalaでは、関数の "カレー化"(それぞれ1つのパラメータを持つ複数のパラメータリスト)を作成することなく、部分的に関数を適用できます。


それはあなたができるようになります:

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

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


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

だからこれ:

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

Tは最初にIntとして推論され、その後、閉包の2つのアンダースコアのタイプとして使用されます。 これは、コンパイラが完全な型の安全性を持って、+演算が有効であることを知る方法です。





partial-application