FoldとfoldLeftとそれぞれのreduceとreduceLeftがどのように機能するかを理解しようとしています。例としてfoldとfoldLeftを使用しました
scala> val r = List((ArrayBuffer(1, 2, 3, 4),10))
scala> r.foldLeft(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
scala> res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5)
scala> r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
<console>:11: error: value _1 is not a member of Serializable with Equals
r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
なぜfold
がfoldLeft
として機能しなかったのですか?とは Serializable with Equals
? foldとfoldLeftには、パラメーターのジェネリック型に関してわずかに異なるAPIシグネチャがあることを理解しています。お知らせ下さい。ありがとう。
メソッドfold
(元々並列計算用に追加された)は、適用可能な型の点でfoldLeft
よりも強力ではありません。その署名は次のとおりです。
_def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
_
これは、折りたたみが行われる型は、コレクション要素型のスーパータイプでなければならないことを意味します。
_def foldLeft[B](z: B)(op: (B, A) => B): B
_
その理由は、fold
を並列に実装できる一方で、foldLeft
は並列に実装できないからです。これは、foldLeft
が左から右に順番に進むことを意味する_*Left
_部分だけでなく、演算子op
が並列に計算された結果を結合できないためです。集約型B
を要素型A
と組み合わせる方法を定義しますが、B
型の2つの集約を組み合わせる方法は定義しません。 fold
メソッドは、これを定義します。これは、集約タイプ_A1
_がエレメントタイプA
のスーパータイプ、つまり_A1 >: A
_である必要があるためです。このスーパータイプの関係により、集約と要素を同時に折りたたみ、集約を組み合わせることができます(両方とも単一の演算子を使用)。
ただし、集計と要素タイプのこのスーパータイプの関係は、例の集計タイプ_A1
_が_(ArrayBuffer[Int], Int)
_のスーパータイプであることも意味します。集計のゼロ要素は_ArrayBuffer[Int]
_型のArrayBuffer(1, 2, 4, 5)
であるため、集計型はこれらの両方のスーパータイプであると推測されます-そしてそれは_Serializable with Equals
_タプルと配列バッファーの上限。
一般に、任意の型の並列フォールディングを許可する場合(順不同で行われます)、2つの集計の結合方法を定義する必要があるaggregate
メソッドを使用する必要があります。あなたの場合:
_r.aggregate(ArrayBuffer(1, 2, 4, 5))({ (x, y) => x -- y._1 }, (x, y) => x intersect y)
_
ところで、reduce
/reduceLeft
を使用して例を書いてみてください-要素タイプとこれら両方のメソッドが持つ集約タイプとのスーパータイプの関係のため、同様の結果につながることがわかります。あなたが説明したようなエラー。