Scala for Backend Engineering & Functional Programming · Leçon

Désucrage de for

map et flatMap

Leçon 1 sur 413 étapes

Désucrage de for est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu’est-ce qu’une compréhension for ?

En Scala, une compréhension for est une syntaxe spéciale permettant de travailler avec des collections et d’autres types conteneurs. Elle ressemble à une boucle impérative, mais c’est en réalité un sucre syntaxique que le compilateur réécrit en appels à map, flatMap, filter et foreach.

Comprendre cette transformation vous aide à raisonner sur toute compréhension for, y compris avec des types personnalisés.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for (x <- List(1, 2, 3)) yield x * 10
    println(result)
  }
}

Un seul générateur devient map

Lorsqu’une compréhension for contient exactement un générateur et utilise yield, le compilateur la réécrit en un seul appel à map.

  • for (x <- xs) yield f(x)
  • devient xs.map(x => f(x))
object Main {
  def main(args: Array[String]): Unit = {
    val a = for (x <- List(1, 2, 3)) yield x + 1
    val b = List(1, 2, 3).map(x => x + 1)
    println(a == b)
  }
}

Le mot-clé yield

Le mot-clé yield indique à Scala de rassembler les résultats dans une nouvelle collection du même type.

Sans yield, la compréhension for exécute un effet de bord pour chaque élément et renvoie Unit (elle devient foreach).

object Main {
  def main(args: Array[String]): Unit = {
    // No yield: side effect only
    for (x <- List("a", "b")) println(x)
    // With yield: builds a new List
    val upper = for (x <- List("a", "b")) yield x.toUpperCase
    println(upper)
  }
}

Deux générateurs deviennent flatMap + map

Avec au moins deux générateurs, les générateurs externes deviennent des appels à flatMap et le générateur le plus interne devient un appel à map.

  • for (x <- xs; y <- ys) yield f(x, y)
  • devient xs.flatMap(x => ys.map(y => f(x, y)))
object Main {
  def main(args: Array[String]): Unit = {
    val pairs = for {
      x <- List(1, 2)
      y <- List("a", "b")
    } yield (x, y)
    println(pairs)
  }
}

Voir l’équivalent avec flatMap

Nous écrivons ici la même logique de deux manières. Démontrer leur équivalence montre que les compréhensions for n’ajoutent aucune magie, seulement de la lisibilité.

object Main {
  def main(args: Array[String]): Unit = {
    val sugar = for {
      x <- List(1, 2)
      y <- List(10, 20)
    } yield x + y

    val desugared = List(1, 2).flatMap(x => List(10, 20).map(y => x + y))

    println(sugar)
    println(sugar == desugared)
  }
}

Pourquoi flatMap pour le générateur externe

Chaque élément externe produit une collection complète de résultats internes. Si nous utilisions map pour le générateur externe, nous obtiendrions une collection imbriquée comme List(List(...), List(...)).

flatMap aplatit ces listes imbriquées en un seul résultat plat.

object Main {
  def main(args: Array[String]): Unit = {
    val nested = List(1, 2).map(x => List(10, 20).map(y => x + y))
    val flat   = List(1, 2).flatMap(x => List(10, 20).map(y => x + y))
    println(nested)
    println(flat)
  }
}

Un for sans yield devient foreach

Une boucle for sans yield est réécrite en foreach. Elle exécute le corps pour ses effets de bord et produit Unit.

  • for (x <- xs) doSomething(x)
  • devient xs.foreach(x => doSomething(x))
object Main {
  def main(args: Array[String]): Unit = {
    val r: Unit = for (x <- List(1, 2, 3)) print(x + " ")
    println()
    println("Return type is Unit")
  }
}

Le type du résultat suit le premier générateur

Le type du résultat est déterminé par la collection du premier générateur. Un for sur une List produit une List ; sur un Set, un Set ; sur un Option, un Option.

object Main {
  def main(args: Array[String]): Unit = {
    val fromList = for (x <- List(1, 2, 2, 3)) yield x
    val fromSet  = for (x <- Set(1, 2, 2, 3)) yield x
    println(fromList)
    println(fromSet)
  }
}

Lier des valeurs avec =

Dans une compréhension for, vous pouvez lier des valeurs intermédiaires avec =. Cela évite de recalculer les mêmes valeurs et améliore la lisibilité.

Cette construction est transformée en un map qui transporte la valeur supplémentaire dans un tuple.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- List(1, 2, 3)
      doubled = x * 2
    } yield doubled + 1
    println(result)
  }
}

Fonctionne avec tout type proposant map/flatMap

Comme la transformation repose uniquement sur map et flatMap, les compréhensions for fonctionnent avec tout type qui définit ces méthodes : Option, Either, Try, Future et vos propres classes.

object Main {
  def main(args: Array[String]): Unit = {
    val combined = for {
      a <- Some(2)
      b <- Some(3)
    } yield a * b
    println(combined)
  }
}

Le véritable avantage est la lisibilité

Comparez une chaîne flatMap/map profondément imbriquée à une compréhension for claire. Elles sont compilées de la même manière, mais la version for se lit de haut en bas comme une recette.

object Main {
  def main(args: Array[String]): Unit = {
    val chained = List(1, 2).flatMap(a => List(3, 4).map(b => a * b))
    val readable = for {
      a <- List(1, 2)
      b <- List(3, 4)
    } yield a * b
    println(chained == readable)
  }
}

Vérification rapide

Comment le compilateur transforme-t-il une compréhension for comportant deux générateurs et un yield ?

Récapitulatif

Vous avez appris comment les compréhensions for sont transformées :

  • Un générateur + yield → map
  • Plusieurs générateurs + yield → flatMap (externe) + map (interne)
  • Sans yield → foreach renvoyant Unit
  • Les liaisons val = ajoutent des valeurs intermédiaires
  • Le type du résultat suit le premier générateur

Tout type possédant map et flatMap peut être utilisé dans une compréhension for.

Gratuit pour commencer

Apprends Scala avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
39
Leçons
143

Questions Fréquemment Posées

La leçon « Désucrage de for » est-elle gratuite ?

Oui — le texte complet de « Désucrage de for » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Désucrage de for » ?

map et flatMap Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Désucrage de for » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Désucrage de for
  2. Filtrer avec if
  3. Générateurs multiples
  4. Utiliser Option et Future
← Retour à Scala for Backend Engineering & Functional Programming