web-dev-qa-db-ja.com

Scala mapメソッドの構文

マトリックスドット積を行う http://www.scalaclass.com/book/export/html/1 からの以下のコード。

中括弧の間の構文を理解できません。

  • 通常のメソッドの括弧ではなく、中括弧が使用されるのはなぜですか?
  • 匿名メソッドですか?
  • ._1および._2とは何ですか?

ありがとう。

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(_ + _)
22
Nabegh
  • 通常のメソッドの括弧ではなく、中括弧が使用されるのはなぜですか?

パラメータが無名関数である場合、中括弧を使用することを好む人もいます。 1つには、中括弧は匿名関数のパターンマッチングを有効にしますが、括弧はそうではありません。この特定の例では、中括弧は必要ありません。

中括弧が必要な例を次に示します(caseパターンマッチングのため)。

_def dotProd(v1:Row, v2:Row) = 
    v1.Zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)
_

上記の関数は、問題の関数と同じことをわずかに異なる方法で実行することに注意してください。

  • tは匿名メソッドですか?

いいえ、それはパラメーターです。 _v1_および_v2_がdotProdのパラメーターであるのと同様に、tmapに渡される無名関数のパラメーターです。

  • _._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)_タプル)を別の要素に変換する関数を取ります。

36

この特定のケースでは、中かっこは従来の構文よりも利点がありませんが、一般的に中かっこを使用する利点は、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要素へのアクセスを提供します。

20
om-nom-nom

この質問では、中括弧{}と括弧()の違いに対する非常に良い答えを見つけることができます。 Scalaの中括弧と括弧の正式な違いは何ですか。それらは使用されますか?

_1、_2については、 _ 2記号の意味scala言語 を参照)。

そして、はい、t:(Double, Double) => t._1 * t._2は匿名関数です(実際にはメソッドではありません)。 Scalaのメソッドと関数の違い

5
Matthew Farwell

中括弧は、タイプTuple2[Double,Double] => Doubleの無名関数を示します。引数にはローカル名tが与えられるため、tは2つのdoubleのタプルです。t._1は最初の項目を参照し、t._2は2番目の項目を参照します。

したがって、mapは2つのベクトルの要素の要素ごとの積のリストを生成し、reduceLeftはこれらの積を合計してドット積を計算します。

1
Lee