Peu de choses à mentionner ici, avant de donner la vraie réponse:
- Votre question n'a rien à voir
left
, elle concerne plutôt la différence entre la réduction et le pliage
- La différence n'est pas du tout l'implémentation, il suffit de regarder les signatures.
- La question n'a rien à voir avec Scala en particulier, elle concerne plutôt les deux concepts de programmation fonctionnelle.
Retour à votre question:
Voici la signature de foldLeft
(aurait également pu être foldRight
pour le point que je vais faire):
def foldLeft [B] (z: B)(f: (B, A) => B): B
Et voici la signature de reduceLeft
(encore une fois, la direction n'a pas d'importance ici)
def reduceLeft [B >: A] (f: (B, A) => B): B
Ces deux aspects sont très similaires et ont donc causé la confusion. reduceLeft
est un cas particulier de foldLeft
(ce qui signifie d'ailleurs que vous pouvez parfois exprimer la même chose en utilisant l'un ou l'autre).
Lorsque vous appelez reduceLeft
say on, List[Int]
cela réduira littéralement toute la liste des entiers en une seule valeur, qui sera de type Int
(ou un super-type de Int
, par conséquent [B >: A]
).
Lorsque vous appelez foldLeft
say on a, List[Int]
il pliera toute la liste (imaginez rouler un morceau de papier) en une seule valeur, mais cette valeur ne doit même pas être liée à Int
(d'où [B]
).
Voici un exemple:
def listWithSum(numbers: List[Int]) = numbers.foldLeft((List.empty[Int], 0)) {
(resultingTuple, currentInteger) =>
(currentInteger :: resultingTuple._1, currentInteger + resultingTuple._2)
}
Cette méthode prend un List[Int]
et retourne un Tuple2[List[Int], Int]
ou (List[Int], Int)
. Il calcule la somme et renvoie un tuple avec une liste d'entiers et sa somme. Soit dit en passant, la liste est renvoyée à l'envers, car nous l'avons utilisé à la foldLeft
place de foldRight
.
Regardez One Fold pour les gouverner tous pour une explication plus approfondie.