0Pricing
Scala for Backend Engineering & Functional Programming · Leçon

Composer Either

map et flatMap

Composer Either est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 3 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.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

Composing Computations

Real programs chain several fallible steps: parse, validate, look up, compute. Either lets you compose these so that the first failure short-circuits the whole chain.

The tools are map, flatMap, and for-comprehensions.

flatMap Sequences Eithers

flatMap applies a function that itself returns an Either. If the receiver is Left, the function is never called and the Left propagates.

object Main {
  def positive(n: Int): Either[String, Int] =
    if (n > 0) Right(n) else Left("not positive")

  def main(args: Array[String]): Unit = {
    val r = Right(5).flatMap(positive)
    val l = Right(-1).flatMap(positive)
    println(r)
    println(l)
  }
}

Short-Circuiting

When you chain multiple flatMap calls, the first Left stops everything. Later steps are skipped, and that error becomes the final result.

object Main {
  def step(label: String, n: Int): Either[String, Int] = {
    println(s"running $label")
    Right(n + 1)
  }

  def main(args: Array[String]): Unit = {
    val result = Left("early error").asInstanceOf[Either[String, Int]]
      .flatMap(n => step("A", n))
      .flatMap(n => step("B", n))
    println(result)
  }
}

for-Comprehension over Either

Because Either is right-biased, you can use it in a for-comprehension. Each <- unwraps a Right; any Left stops the comprehension and becomes the result.

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("4")
    } yield a + b
    println(sum)
  }
}

A Failing for-Comprehension

If any step in the comprehension yields a Left, the whole expression is that Left and subsequent steps do not run.

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("oops")
      c <- parse("5")
    } yield a + b + c
    println(sum)
  }
}

Chaining Validations

A realistic pipeline: parse a string, then check a business rule, then transform. Each stage returns an Either.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight("not a number")
  def checkRange(n: Int): Either[String, Int] =
    if (n >= 1 && n <= 100) Right(n) else Left("out of range")

  def process(s: String): Either[String, Int] =
    parse(s).flatMap(checkRange).map(_ * 10)

  def main(args: Array[String]): Unit = {
    println(process("7"))
    println(process("500"))
    println(process("x"))
  }
}

map vs flatMap

Use map when your function returns a plain value. Use flatMap when it returns another Either, to avoid a nested Either[String, Either[String, Int]].

@main def run(): Unit = {
  val withMap: Either[String, Int] = Right(2).map(_ + 1)
  val nested: Either[String, Either[String, Int]] = Right(2).map(n => Right(n + 1))
  val flat: Either[String, Int] = Right(2).flatMap(n => Right(n + 1))
  println(withMap)
  println(nested)
  println(flat)
}

Combining Independent Values

A for-comprehension also works when each step does not depend on the previous one. All must succeed for the final yield to run.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- parse("10")
      y <- parse("20")
      z <- parse("30")
    } yield List(x, y, z).sum
    println(combined)
  }
}

leftMap-Style Error Transformation

Standard library Either has no leftMap, but you can transform the error with swap.map(...).swap or by mapping inside a fold. This keeps error types consistent across a pipeline.

@main def run(): Unit = {
  val e: Either[String, Int] = Left("low-level error")
  val mapped = e.swap.map(msg => s"context: $msg").swap
  println(mapped)
}

Putting It All Together

A small calculator pipeline that parses two numbers and divides, reporting any failure as a typed error.

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad number: $s")
  def divide(a: Int, b: Int): Either[String, Int] =
    if (b == 0) Left("division by zero") else Right(a / b)

  def calc(x: String, y: String): Either[String, Int] =
    for {
      a <- parse(x)
      b <- parse(y)
      r <- divide(a, b)
    } yield r

  def main(args: Array[String]): Unit = {
    println(calc("20", "4"))
    println(calc("20", "0"))
    println(calc("x", "4"))
  }
}

Why This Matters

Composing Either gives you railway-oriented programming: the happy path flows through Right, and any error diverts onto the Left track and bypasses the rest. No exceptions, no null checks, just values.

Quick Check

Test your understanding of composing Either.

Recap

You learned to compose Either:

  • flatMap sequences fallible steps and short-circuits on the first Left.
  • for-comprehensions read cleanly for multi-step pipelines.
  • Use map for plain results, flatMap for Either-returning functions.
  • Transform errors with swap.map(...).swap.

Questions Fréquemment Posées

La leçon « Composer Either » est-elle gratuite ?

Oui — le texte complet de « Composer Either » 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 « Composer Either » ?

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 3 sur 4.

Combien de temps prend la leçon « Composer Either » ?

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. Either pour les erreurs
  2. Try, Success, Failure
  3. Composer Either
  4. Convertir entre les types
← Retour à Scala for Backend Engineering & Functional Programming