3

Scala Style Guide - Method Invocationを何度か読んだにもかかわらず、私はこれについてしばらく混乱していました。

このメソッドを呼び出せるようにしたい

def foldRVL[A,B](l: List[A], z: B)(f: (A, B) => B) = //"Right-Via-Left"
  l.reverse.foldLeft(z)((a, b) => f(b, a))

このようにドット表記を使用しList(1,2,3).foldRVL(0)(_ + _)ます。

そして、このようではありません: foldRVL(List(1,2,3), 0)(_ + _).

また、署名で実際にゼロのパラメーターを受け取るか、予想よりも 1 つ少ないパラメーターを受け取り、ドット表記を使用して適切にパラメーターを受け取るメソッドを示すコードを時々見ました。これはどのように作動しますか?これらのメソッドはドット表記で機能するため、これを尋ねます。そのため、そのようなものを書いた場合、問題を解決できるかもしれません。

4

2 に答える 2

5

質問の最初の部分については、おそらく暗黙のクラスを確認する必要があります。

  implicit class RichRVLList[A](l:List[A]) {
    def foldRVL[B](z: B)(f: (A, B) => B) = //"Right-Via-Left"
      l.reverse.foldLeft(z)((a, b) => f(b, a))
  }

  List(1,2,3).foldRVL(1)(_ + _)  // output: res0: Int = 7

暗黙的なラッパーを使用して既存のクラスを「強化」し、新しいメソッドを「追加」できます。

2 番目の部分については、おそらく暗黙のパラメーターが必要です。暗黙的なパラメーターは、現在のスコープから型別に推測されます。Numerics以下の例で使用されているなど、事前定義された暗黙的な値がいくつかあります。

  def product[T](els:TraversableOnce[T])(implicit num:Numeric[T]) = {
    els.fold(num.one)((x1, x2) => num.times(x1, x2))
  }      

  product(List(1, 2, 3)) // res1: Int = 6
  product(List(1, 2.5, 3)) //res2: Double = 7.5
于 2015-07-25T00:57:40.827 に答える
1

soong は、私が実際に 'Pimp my library' パターンを探していることを指摘し、それを調べて、問題のメソッドを処理するために次のように実装しました。

implicit class BlingList[+A](l: List[A]) {
  def foldRVL[B](z: B)(f: (A, B) => B): B = //"Right-Via-Left"
    l.foldLeft(z)((a, b) => f(b, a))
}

私が理解している限り、ドット表記を許可するための重要な要素は、「pimped」したい型のパラメーターを取るクラス構成を持つことです。foldRVLこの場合、リストがあり、次のように、リストを書き留めた後でリスト を呼び出したいと考えていますList(something).foldRVL(z)(f: A => B)List[A]したがって、最初のコード スニペットでそのようなメソッドを記述できるようにするには、パラメーターを受け取るクラスが必要です。

このimplicitキーワードはclass List、メソッドのライブラリを個別に作成しなくても、既存のメソッドを追加できるようにするために使用されます。の前に接頭辞が付いている aListが見つかった場合は常にfoldRVL、暗黙的に a に変換されます。BlingListこれは、コンパイラが にList存在しないメソッドにアタッチされていることを確認するためclass Listです。foldRVLしたがって、メソッドを持ち、引数として を受け取る、スコープ内で定義された暗黙的なメソッドを探し、メソッドが定義されていてを受け取るListを見つけます。したがって、私は今書くことができます:implicit class BlingListfoldRVLList[A]

List(1,2,3).foldRVL(0)(_ + _) // in some IDE's, foldRVL will be underlined to show that
res0: Int = 6                 // an implicit conversion is being made

「Scala 2.10 の暗黙的なクラスの例」では、これについてさらに詳しく説明しています。その投稿からの私のお気に入りのポインタは、現在のパッケージとサブパッケージで使用することが予想されるすべての暗黙的なクラスを .xml 内に配置するpackage objectことです。これにより、クラスやオブジェクトを暗黙的なクラス定義で混乱させる必要がなくなります。それらをインポートする必要もありません。それらが同じパッケージを使用しているという事実は、package object.

于 2015-07-25T00:53:55.483 に答える