Несколько вещей, чтобы упомянуть здесь, прежде чем дать фактический ответ:
- Ваш вопрос не имеет ничего общего с
left, а скорее о разнице между уменьшением и сворачиванием
- Разница вовсе не в реализации, просто посмотрите на подписи.
- Вопрос, в частности, не имеет ничего общего со Scala, а скорее о двух концепциях функционального программирования.
Вернуться к вашему вопросу:
Вот подпись foldLeft(также могла бы послужить foldRightпричиной, которую я собираюсь изложить):
def foldLeft [B] (z: B)(f: (B, A) => B): B
А вот и подпись reduceLeft(опять же направление здесь не имеет значения)
def reduceLeft [B >: A] (f: (B, A) => B): B
Эти два выглядят очень похожими и, таким образом, вызвали путаницу. reduceLeftэто особый случай foldLeft(что, кстати, означает, что иногда вы можете выразить одно и то же, используя любой из них).
Когда вы вызываете reduceLeftsay для a, List[Int]это буквально сократит весь список целых чисел до единого значения, которое будет иметь тип Int(или Int, следовательно, супертип [B >: A]).
Когда вы вызываете foldLeftsay для a, List[Int]он свернет весь список (представьте, что вы катите лист бумаги) в одно значение, но это значение не обязательно должно даже быть связано с Int(следовательно [B]).
Вот пример:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Этот метод принимает List[Int]и возвращает Tuple2[List[Int], Int]или (List[Int], Int). Он вычисляет сумму и возвращает кортеж со списком целых чисел и его суммой. Кстати, список возвращается в обратном порядке, потому что мы использовали foldLeftвместо foldRight.
Смотрите One Fold, чтобы править ими все для более глубокого объяснения.