マトリックスドット積を行う http://www.scalaclass.com/book/export/html/1 からの以下のコード。
中括弧の間の構文を理解できません。
ありがとう。
type Row = List[Double]
type Matrix = List[Row]
def dotProd(v1:Row, v2:Row) =
v1.Zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _)
パラメータが無名関数である場合、中括弧を使用することを好む人もいます。 1つには、中括弧は匿名関数のパターンマッチングを有効にしますが、括弧はそうではありません。この特定の例では、中括弧は必要ありません。
中括弧が必要な例を次に示します(case
パターンマッチングのため)。
_def dotProd(v1:Row, v2:Row) =
v1.Zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)
_
上記の関数は、問題の関数と同じことをわずかに異なる方法で実行することに注意してください。
t
は匿名メソッドですか?いいえ、それはパラメーターです。 _v1
_および_v2
_がdotProd
のパラメーターであるのと同様に、t
はmap
に渡される無名関数のパラメーターです。
._1
_および_._2
_とは何ですか?t
のメソッド。パラメータt
はタプル(具体的には_Tuple2[Double, Double]
_、_(Double, Double)
_として記述できる)として定義されており、タプルを使用すると、次のようなメソッドでタプルの各メンバーを抽出できます。 __1
_、__2
_、__3
_など.
もちろん、_Tuple2
_には__1
_と__2
_しかありません。他の関数型言語からの影響のため、最初のパラメータは__1
_ではなく__0
_であることに注意してください。
とにかく、Zip
メソッドはRow
(_List[Double]
_)をList[(Double, Double)]
に変換します。メソッドmap
は、リストの要素(_(Double, Double)
_タプル)を別の要素に変換する関数を取ります。
この特定のケースでは、中かっこは従来の構文よりも利点がありませんが、一般的に中かっこを使用する利点は、map ...
内にパターンマッチング式を記述できることです。
これを書き直すことができます
.map{ t:(Double, Double) => t._1 * t._2 }
これに
.map{ case(a: Double, b: Double) => a*b }
しかし、これはコンパイルされません:
.map( case(a: Double, b: Double) => a*b )
リーが言ったように、._ 1、._ 2は、Nタプルの1番目、2番目、... N要素へのアクセスを提供します。
この質問では、中括弧{}と括弧()の違いに対する非常に良い答えを見つけることができます。 Scalaの中括弧と括弧の正式な違いは何ですか。それらは使用されますか?
_1、_2については、 _ 2記号の意味scala言語 を参照)。
そして、はい、t:(Double, Double) => t._1 * t._2
は匿名関数です(実際にはメソッドではありません)。 Scalaのメソッドと関数の違い
中括弧は、タイプTuple2[Double,Double] => Double
の無名関数を示します。引数にはローカル名t
が与えられるため、t
は2つのdoubleのタプルです。t._1
は最初の項目を参照し、t._2
は2番目の項目を参照します。
したがって、map
は2つのベクトルの要素の要素ごとの積のリストを生成し、reduceLeft
はこれらの積を合計してドット積を計算します。