Несколько вещей, о которых стоит упомянуть здесь, прежде чем дать фактический ответ:
- Ваш вопрос не имеет ничего общего с
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
скажем, на List[Int]
он буквально сократит весь список целых чисел до одного значения, которое будет иметь тип Int
(или супертип Int
, следовательно, [B >: A]
).
Когда вы вызываете foldLeft
скажем, на List[Int]
он свернет весь список (представьте, что вы катите лист бумаги) в одно значение, но это значение не обязательно должно быть даже связано с Int
(следовательно, [B]
).
Вот пример:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List[Int](), 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Этот метод принимает List[Int]
и возвращает Tuple2[List[Int], Int]
или (List[Int] -> Int)
.Он вычисляет сумму и возвращает кортеж со списком целых чисел и его суммой.Кстати, список возвращается в обратном порядке, потому что мы использовали foldLeft
вместо foldRight
.
Watch One Fold, чтобы править ими всеми для более подробного объяснения.