Poche cose da menzionare qui, prima di dare la risposta effettiva:
- La tua domanda non ha nulla a che fare con
left
, riguarda piuttosto la differenza tra ridurre e piegare
- La differenza non è affatto l'implementazione, basta guardare le firme.
- La domanda non ha nulla a che fare con Scala in particolare, riguarda piuttosto i due concetti di programmazione funzionale.
Torna alla tua domanda:
Ecco la firma di foldLeft
(potrebbe anche essere stato foldRight
per il punto che farò):
def foldLeft [B] (z: B)(f: (B, A) => B): B
Ed ecco la firma di reduceLeft
(di nuovo la direzione non conta qui)
def reduceLeft [B >: A] (f: (B, A) => B): B
Questi due sembrano molto simili e quindi hanno causato confusione. reduceLeft
è un caso speciale di foldLeft
(che a proposito significa che a volte puoi esprimere la stessa cosa usando uno di essi).
Quando chiami reduceLeft
say su a List[Int]
, ridurrà letteralmente l'intero elenco di numeri interi in un singolo valore, che sarà di tipo Int
(o un supertipo di Int
, quindi [B >: A]
).
Quando chiami foldLeft
dire su un List[Int]
, piegherà l'intero elenco (immagina di arrotolare un pezzo di carta) in un singolo valore, ma questo valore non deve essere nemmeno correlato a Int
(quindi [B]
).
Ecco un esempio:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Questo metodo accetta a List[Int]
e restituisce a Tuple2[List[Int], Int]
o (List[Int], Int)
. Calcola la somma e restituisce una tupla con un elenco di numeri interi ed è la somma. A proposito, l'elenco viene restituito al contrario, perché abbiamo usato al foldLeft
posto di foldRight
.
Guarda One Fold per domarli tutti per una spiegazione più approfondita.