Poucas coisas para mencionar aqui, antes de dar a resposta real:
- Sua pergunta não tem nada a ver
left, é sobre a diferença entre reduzir e dobrar
- A diferença não é a implementação, basta olhar para as assinaturas.
- A questão não tem nada a ver com Scala em particular, é sobre os dois conceitos de programação funcional.
Voltar à sua pergunta:
Aqui está a assinatura de foldLeft(também poderia ter sido foldRightpara o ponto que eu vou fazer):
def foldLeft [B] (z: B)(f: (B, A) => B): B
E aqui está a assinatura de reduceLeft(novamente a direção não importa aqui)
def reduceLeft [B >: A] (f: (B, A) => B): B
Estes dois parecem muito semelhantes e, portanto, causaram confusão. reduceLefté um caso especial de foldLeft(que, a propósito, significa que você às vezes pode expressar a mesma coisa usando qualquer um deles).
Quando você chama reduceLeftsay em a List[Int], literalmente reduz a lista inteira de números inteiros em um único valor, que será do tipo Int(ou um supertipo de Int, portanto [B >: A]).
Quando você chama o foldLeftsay em um, List[Int]ele dobrará a lista inteira (imagine rolar um pedaço de papel) em um único valor, mas esse valor nem precisa estar relacionado aInt (daí [B]).
Aqui está um exemplo:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Este método pega um List[Int]e retorna um Tuple2[List[Int], Int]ou (List[Int], Int). Ele calcula a soma e retorna uma tupla com uma lista de números inteiros e sua soma. A propósito, a lista é retornada para trás, porque usamos em foldLeftvez defoldRight .
Assista ao One Fold para dominá-los para uma explicação mais aprofundada.