Différence entre foldle et foldLeft ou foldRight?

NOTE: je suis sur Scala 2.8-peut-être un problème?

pourquoi ne puis-je pas utiliser la fonction fold de la même manière que foldLeft ou foldRight ?

Dans le Set scaladoc il est dit que:

le résultat du pliage ne peut être qu'un supertype du paramètre de type de cette collection parallèle T .

mais je ne vois aucun paramètre de type T dans la fonction signature:

def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1

Quelle est la différence entre le foldLeft-Right et le fold , et comment utiliser ce dernier?

EDIT: par exemple comment écrire un pli pour ajouter tous les éléments d'une liste? Avec foldLeft ce serait:

val foo = List(1, 2, 3)
foo.foldLeft(0)(_ + _)

// now try fold:
foo.fold(0)(_ + _)
>:7: error: value fold is not a member of List[Int]
  foo.fold(0)(_ + _)
    ^
60
demandé sur drozzy 2011-06-06 18:58:55

5 réponses

vous avez raison à propos de L'ancienne version de Scala étant un problème. Si vous regardez la scaladoc page pour Scala 2.8.1, vous ne verrez aucun pli défini (ce qui est compatible avec votre message d'erreur). Apparemment, fold a été introduit dans Scala 2.9.

8
répondu exlevan 2011-06-08 21:34:37

courte réponse:

foldRight associés à droite. I. e. les éléments seront accumulés dans de droite à gauche:

List(a,b,c).foldRight(z)(f) = f(a, f(b, f(c, z)))

foldLeft associés à gauche. I. e. un accumulateur sera initialisé et les éléments seront ajoutés à l'accumulateur de gauche à droite:

List(a,b,c).foldLeft(z)(f) = f(f(f(z, a), b), c)

fold est associatif dans l'ordre dans lequel les éléments sont ajoutés ensemble n'est pas défini. C'est-à-dire: les arguments de fold forment un monoid .

60
répondu Apocalisp 2016-12-20 16:58:51

fold , contrairement à foldRight et foldLeft , n'offre aucune garantie quant à l'ordre dans lequel les éléments de la collection seront traitées. Vous voudrez probablement utiliser fold , avec sa signature plus restreinte, avec des collections parallèles, où le manque d'ordre de traitement garanti aide la collection parallèle outils pliage d'une manière parallèle. La raison pour changer la signature est similaire: avec les contraintes supplémentaires, il est plus facile de faites un pli parallèle.

52
répondu Jean-Philippe Pellet 2011-06-06 15:11:40

pour votre exemple particulier, vous le coderiez de la même façon que vous le feriez avec foldLeft.

val ns = List(1, 2, 3, 4)
val s0 = ns.foldLeft (0) (_+_) //10
val s1 = ns.fold (0) (_+_) //10
assert(s0 == s1)
3
répondu Garrett Rowe 2011-06-06 18:25:00

d'Accord avec les autres réponses. j'ai pensé à donner un exemple simple:

 object MyClass {
 def main(args: Array[String]) {
val numbers = List(5, 4, 8, 6, 2)
 val a =  numbers.fold(0) { (z, i) =>
 {
     println("fold val1 " + z +" val2 " + i)
  z + i

 }
}
println(a)
 val b =  numbers.foldLeft(0) { (z, i) =>
 println("foldleft val1 " + z +" val2 " + i)
  z + i

}
println(b)
   val c =  numbers.foldRight(0) { (z, i) =>
   println("fold right val1 " + z +" val2 " + i)
  z + i

}
println(c)
 }
}

Résultat est explicite :

fold val1 0 val2 5
fold val1 5 val2 4
fold val1 9 val2 8
fold val1 17 val2 6
fold val1 23 val2 2
25
foldleft val1 0 val2 5
foldleft val1 5 val2 4
foldleft val1 9 val2 8
foldleft val1 17 val2 6
foldleft val1 23 val2 2
25
fold right val1 2 val2 0
fold right val1 6 val2 2
fold right val1 8 val2 8
fold right val1 4 val2 16
fold right val1 5 val2 20
25
3
répondu Ram Ghadiyaram 2017-04-20 05:39:15