Kilka rzeczy, o których warto tu wspomnieć, zanim podamy właściwą odpowiedź:
- Twoje pytanie nie ma nic wspólnego z
left, dotyczy raczej różnicy między zmniejszaniem a składaniem
- Różnica nie polega wcale na implementacji, wystarczy spojrzeć na podpisy.
- Pytanie nie ma nic wspólnego ze Scalą, chodzi raczej o dwie koncepcje programowania funkcjonalnego.
Powrót do pytania:
Oto podpis foldLeft(mógłbym również zrobić foldRightpunkt, który zamierzam zrobić):
def foldLeft [B] (z: B)(f: (B, A) => B): B
A oto podpis reduceLeft(znowu kierunek nie ma tutaj znaczenia)
def reduceLeft [B >: A] (f: (B, A) => B): B
Te dwa wyglądają bardzo podobnie, powodując zamieszanie. reduceLeftjest szczególnym przypadkiem foldLeft(co przy okazji oznacza, że czasami możesz wyrazić to samo, używając jednego z nich).
Kiedy wywołasz reduceLeftsay na a List[Int], dosłownie zredukuje całą listę liczb całkowitych do pojedynczej wartości, która będzie typu Int(lub Intodtąd typu [B >: A]).
Kiedy wywołasz foldLeftsay na a List[Int], zwinie całą listę (wyobraź sobie zwinięcie kartki papieru) w jedną wartość, ale ta wartość nie musi być nawet związana Int(stąd [B]).
Oto przykład:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Ta metoda pobiera a List[Int]i zwraca a Tuple2[List[Int], Int]lub (List[Int], Int). Oblicza sumę i zwraca krotkę z listą liczb całkowitych i jej sumy. Nawiasem mówiąc, lista jest zwracana wstecz, ponieważ użyliśmy foldLeftzamiast foldRight.
Obejrzyj One Fold, aby rządzić nimi wszystkimi, by uzyskać bardziej szczegółowe wyjaśnienia.