Il metodo fold
(originariamente aggiunto per il calcolo parallelo) è meno potente di foldLeft
in termini di tipi a cui può essere applicato. La sua firma è:
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
Ciò significa che il tipo su cui viene eseguita la piegatura deve essere un supertipo del tipo di elemento di raccolta.
def foldLeft[B](z: B)(op: (B, A) => B): B
La ragione è che fold
può essere implementato in parallelo, mentre foldLeft
non può. Questo non è solo a causa della parte *Left
che implica che foldLeft
passa da sinistra a destra in sequenza, ma anche perché l'operatore op
non può combinare i risultati calcolati in parallelo - definisce solo come combinare il tipo di aggregazione B
con il tipo di elemento A
, ma non come combinare due aggregazioni di tipo B
. Il metodo fold
, a sua volta, definisce questo, perché il tipo di aggregazione A1
deve essere un supertipo del tipo di elemento A
, ovvero A1 >: A
. Questa relazione supertipo consente allo stesso tempo di piegare l'aggregazione e gli elementi e di combinare le aggregazioni, sia con un singolo operatore.
Tuttavia, questa relazione di supertipo tra l'aggregazione e il tipo di elemento indica anche che il tipo di aggregazione A1
nell'esempio dovrebbe essere il supertipo di (ArrayBuffer[Int], Int)
. Poiché l'elemento zero della tua aggregazione è ArrayBuffer(1, 2, 4, 5)
del tipo ArrayBuffer[Int]
, il tipo di aggregazione viene considerato come il supertipo di entrambi, e questo è Serializable with Equals
, l'unico limite superiore di una tupla e un buffer di matrice.
In generale, se si desidera consentire la piegatura parallela per tipi arbitrari (operazione eseguita fuori servizio), è necessario utilizzare il metodo aggregate
che richiede la definizione di come vengono combinate due aggregazioni. Nel tuo caso:
r.aggregate(ArrayBuffer(1, 2, 4, 5))({ (x, y) => x -- y._1 }, (x, y) => x intersect y)
Btw, provare a scrivere il vostro esempio con reduce
/reduceLeft
- a causa del rapporto supertipo tra il tipo di elemento e il tipo di aggregazione che entrambi questi metodi hanno, troverete che porta a un errore simile a quello che hai descritto.
Possibile duplicato di [Differenza tra piega e piega sinistra o piega destra?] (Http://stackoverflow.com/q/6253978) –
Quale versione di scala? –
La mia versione di scala è 2.10.1 – thlim