4

J'essaie d'apprendre la programmation fonctionnelle et Scala, donc je lis la "Programmation fonctionnelle en Scala" par Chiusano et Bjarnason. J'ai de la difficulté à comprendre ce que les méthodes de pli gauche et pli droit font en cas de liste. J'ai regardé autour d'ici mais je n'ai pas trouvé quelque chose de débutant amical. Ainsi, le code fourni par le livre est:Scala plier à droite et plier à gauche

def foldRight[A,B](as: List[A], z: B)(f: (A, B) => B): B = as match { 
    case Nil => z 
    case Cons(h, t) => f(h, foldRight(t, z)(f)) 
} 

def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match { 
    case Nil => z 
    case Cons(h,t) => foldLeft(t, f(z,h))(f) 
} 

Où Cons et Nil sont:

case class Cons[+A](head: A, tail: List[A]) extends List[A] 
case object Nil extends List[Nothing] 

Alors qu'est-ce pli effectivement gauche et à droite faire? Pourquoi sont nécessaires en tant que "utilité" des méthodes? Il y a beaucoup d'autres méthodes qui les utilisent et j'ai du mal à les comprendre aussi, puisque je ne comprends pas ces deux-là.

+0

jetez un oeil à la discussion suivante. http://stackoverflow.com/questions/24370549/foldleft-v-foldright-does-it-matter Il y a beaucoup d'informations concernant ces opérations. On dirait un doublon pour moi. – Pavel

+0

Dans cette question, il semble que l'utilisateur demandant a une très bonne compréhension de l'affaire, je ne sais pas, ce qui est ce que je veux aider. – jrsall92

+2

Pour le code que vous avez fourni. Avez-vous une question spécifique? Qu'est-ce qui crée exactement une difficulté? syntaxe? La clé pour comprendre la différence est la façon dont l'appel récursif se fait dans les deux cas. C'est différent. Lisez à propos de la récursivité de la queue. J'espère que cela aidera. Plus de liens: https://oldfashionedsoftware.com/2009/07/10/scala-code-review-foldleft-and-foldright/ – Pavel

Répondre

7

Selon mon expérience, l'une des meilleures façons d'entraînement l'intuition est de voir comment il fonctionne sur les exemples très simples:

List(1, 3, 8).foldLeft(100)(_ - _) == ((100 - 1) - 3) - 8 == 88 
List(1, 3, 8).foldRight(100)(_ - _) == 1 - (3 - (8 - 100)) == -94 

Comme vous pouvez le voir, foldLeft/Right passe juste l'élément de la liste et le résultat de l'application précédente à l'opération en secondes parenthèses. Il convient également de mentionner que si vous appliquez ces méthodes à la même liste, elles ne renverront des résultats égaux que si l'opération appliquée est associative.

+0

Je pense que vous vouliez que votre opération soit '(_ - _)', c'est-à-dire moins au lieu de plus. Sinon, une très bonne explication des différences entre foldLeft et foldRight. – melston

1

Dites que vous avez une liste de nombres, et vous voulez les ajouter tous. Comment feriez-vous cela? Vous ajoutez le premier et le second, puis prenez le résultat de cela, ajoutez-le au troisième, prenez le résultat de cela, ajoutez-le au quatrième et ainsi de suite.

C'est ce que vous pliez.

List(1,2,3,4,5).foldLeft(0)(_ + _) 

Le « + » est la fonction que vous souhaitez appliquer, avec le premier opérande étant le résultat de son application aux éléments jusqu'à présent, et le second opérande étant l'élément suivant. Comme vous n'avez pas de "résultat jusqu'ici" pour la première application, vous fournissez une valeur de départ - dans ce cas 0, car c'est l'élément d'identité pour l'addition.

que vous voulez multiplier tous vos éléments de la liste, avec pli, ce serait

List(1,2,3,4,5).foldLeft(1)(_ * _) 

Fold dispose de son propre Wikipedia page vous pouvez vérifier.

Bien sûr, il existe également des entrées ScalaDoc pour foldLeft et foldRight.