Несколько вещей, чтобы упомянуть здесь, прежде чем дать фактический ответ:
- Ваш вопрос не имеет ничего общего с
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
(что, кстати, означает, что иногда вы можете выразить одно и то же, используя любой из них).
Когда вы вызываете reduceLeft
say для a, List[Int]
это буквально сократит весь список целых чисел до единого значения, которое будет иметь тип Int
(или Int
, следовательно, супертип [B >: A]
).
Когда вы вызываете foldLeft
say для 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, чтобы править ими все для более глубокого объяснения.