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 foldRightper 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 reduceLeftsay 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 foldLeftdire 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 foldLeftposto di foldRight.
Guarda One Fold per domarli tutti per una spiegazione più approfondita.