0Pricing
Scala for Backend Engineering & Functional Programming · Lección

Composición de Either

map y flatMap

Composición de Either es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

Componer cálculos

Los programas reales encadenan varios pasos que pueden fallar: analizar, validar, buscar y calcular. Either le permite componerlos de modo que el primer fallo interrumpa toda la cadena.

Las herramientas son map, flatMap y las comprensiones for.

flatMap secuencia Eithers

flatMap aplica una función que a su vez devuelve un Either. Si el receptor es Left, la función nunca se llama y el Left se propaga.

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)
  }
}

Interrupción inmediata

Cuando encadena varias llamadas a flatMap, el primer Left detiene todo. Los pasos posteriores se omiten y ese error se convierte en el resultado final.

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)
  }
}

Comprensión for sobre Either

Como Either tiene sesgo hacia Right, puede usarlo en una comprensión for. Cada <- extrae el valor de un Right; cualquier Left detiene la comprensión y se convierte en el resultado.

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)
  }
}

Una comprensión for fallida

Si algún paso de la comprensión produce un Left, toda la expresión es ese Left y los pasos posteriores no se ejecutan.

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)
  }
}

Encadenar validaciones

Una canalización realista: analice una cadena, compruebe después una regla de negocio y, por último, transforme el resultado. Cada etapa devuelve un 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 frente a flatMap

Use map cuando su función devuelva un valor simple. Use flatMap cuando devuelva otro Either, para evitar un Either[String, Either[String, Int]] anidado.

@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)
}

Combinar valores independientes

Una comprensión for también funciona cuando cada paso no depende del anterior. Todos deben completarse correctamente para que se ejecute el yield final.

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)
  }
}

Transformación de errores al estilo leftMap

La biblioteca estándar Either no tiene leftMap, pero puede transformar el error con swap.map(...).swap o asignando dentro de un fold. Así se mantienen coherentes los tipos de error en toda la canalización.

@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)
}

Unirlo todo

Una pequeña canalización de calculadora que analiza dos números y los divide, informando de cualquier fallo como un error tipado.

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"))
  }
}

Por qué es importante

Componer Either le proporciona una programación orientada a raíles: el flujo normal avanza por Right, y cualquier error se desvía a la vía Left y evita el resto del proceso. Sin excepciones, sin comprobaciones de valores nulos, solo valores.

Comprobación rápida

Compruebe su comprensión de la composición de Either.

Resumen

Ha aprendido a componer Either:

  • flatMap secuencia pasos que pueden fallar e interrumpe la cadena en el primer Left.
  • Las comprensiones for permiten expresar claramente las canalizaciones de varios pasos.
  • Use map para resultados simples y flatMap para funciones que devuelven Either.
  • Transforme los errores con swap.map(...).swap.

Preguntas frecuentes

¿La lección «Composición de Either» es gratis?

Sí — el texto completo de «Composición de Either» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

¿Qué aprenderé en «Composición de Either»?

map y flatMap Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?

No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Composición de Either»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?

Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Either para errores
  2. Try, Success, Failure
  3. Composición de Either
  4. Conversión entre tipos
← Volver a Scala for Backend Engineering & Functional Programming