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ć foldRight
punkt, 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. reduceLeft
jest szczególnym przypadkiem foldLeft
(co przy okazji oznacza, że czasami możesz wyrazić to samo, używając jednego z nich).
Kiedy wywołasz reduceLeft
say na a List[Int]
, dosłownie zredukuje całą listę liczb całkowitych do pojedynczej wartości, która będzie typu Int
(lub Int
odtąd typu [B >: A]
).
Kiedy wywołasz foldLeft
say 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 foldLeft
zamiast foldRight
.
Obejrzyj One Fold, aby rządzić nimi wszystkimi, by uzyskać bardziej szczegółowe wyjaśnienia.