Uso con Option y Future
Encadenamiento monádico
Uso con Option y Future es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 4 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.
Más allá de las colecciones
Las for-comprehensions no se limitan a las listas. Se puede utilizar cualquier tipo que proporcione map y flatMap, incluidos Option, Either, Try y Future. Esto se denomina encadenamiento monádico.
object Main {
def main(args: Array[String]): Unit = {
val sum = for {
a <- Some(10)
b <- Some(20)
} yield a + b
println(sum)
}
}Option se detiene en None
Con Option, la comprensión produce un resultado solo si todos los generadores son Some. Si alguno es None, todo el resultado es None y se omiten los pasos posteriores.
object Main {
def main(args: Array[String]): Unit = {
val ok = for {
a <- Some(2)
b <- Some(3)
} yield a * b
val missing = for {
a <- Some(2)
b <- None: Option[Int]
} yield a * b
println(ok)
println(missing)
}
}Encadenar búsquedas opcionales
Un patrón habitual es buscar claves en un Map, donde cada búsqueda devuelve un Option. La for-comprehension produce un valor solo si todas las búsquedas tienen éxito.
object Main {
def main(args: Array[String]): Unit = {
val prices = Map("apple" -> 3, "bread" -> 5)
val total = for {
a <- prices.get("apple")
b <- prices.get("bread")
} yield a + b
println(total)
val missing = for {
a <- prices.get("apple")
c <- prices.get("milk")
} yield a + c
println(missing)
}
}Por qué es mejor que los if-else anidados
Sin for-comprehensions tendría que anidar comprobaciones de patrones o comprobaciones de valores nulos. La forma monádica aplana esa pirámide y la convierte en una secuencia lineal clara.
object Main {
def parse(s: String): Option[Int] = s.toIntOption
def main(args: Array[String]): Unit = {
val result = for {
x <- parse("40")
y <- parse("2")
} yield x + y
println(result)
}
}Las guardas también funcionan con Option
Una guarda dentro de una comprensión de Option convierte un valor en None cuando no se cumple la condición, actuando como una validación integrada.
object Main {
def main(args: Array[String]): Unit = {
def validate(age: Int): Option[Int] =
for {
a <- Some(age)
if a >= 18
} yield a
println(validate(25))
println(validate(15))
}
}Introducción a Future
Un Future representa un valor que estará disponible más adelante. Al igual que Option, tiene map y flatMap, por lo que las for-comprehensions encadenan pasos asíncronos.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val f = for {
a <- Future(10)
b <- Future(20)
} yield a + b
println(Await.result(f, 2.seconds))
}
}Aquí los Future se ejecutan secuencialmente
Cuando un generador depende de otro dentro de una for-comprehension, los future se ejecutan en secuencia, porque cada flatMap espera el resultado anterior.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val f = for {
a <- Future(5)
b <- Future(a * 2)
} yield a + b
println(Await.result(f, 2.seconds))
}
}Ejecutar future en paralelo
Para ejecutar future en paralelo, inícielos antes de la for-comprehension y, después, combínelos. Las tareas independientes se solapan en lugar de esperar.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val fa = Future(100)
val fb = Future(200)
val combined = for {
a <- fa
b <- fb
} yield a + b
println(Await.result(combined, 2.seconds))
}
}Either para obtener errores más completos
Either[E, A] contiene un valor de error cuando se produce un fallo. En una for-comprehension, el primer Left detiene el procesamiento y se devuelve.
object Main {
def parse(s: String): Either[String, Int] =
s.toIntOption.toRight(s"not a number: $s")
def main(args: Array[String]): Unit = {
val good = for { a <- parse("3"); b <- parse("4") } yield a + b
val bad = for { a <- parse("3"); b <- parse("x") } yield a + b
println(good)
println(bad)
}
}La misma estructura para muchos tipos
Observe que la comprensión tiene el mismo aspecto tanto si utiliza Option, Either, Try o Future. Solo cambia la semántica de los fallos. Esta uniformidad es el poder del encadenamiento monádico.
import scala.util.Try
object Main {
def main(args: Array[String]): Unit = {
val result = for {
a <- Try("21".toInt)
b <- Try("2".toInt)
} yield a * b
println(result)
}
}No se permite mezclar tipos
Todos los generadores de una comprensión deben pertenecer a la misma mónada. No puede mezclar directamente un generador de Option con uno de Future; primero debe convertir uno de ellos, por ejemplo con Future.fromTry, o envolver el Option.
object Main {
def main(args: Array[String]): Unit = {
// Convert the Option to keep types consistent
val maybe: Option[Int] = Some(7)
val result = for {
a <- maybe
b <- maybe.map(_ + 1)
} yield a + b
println(result)
}
}Comprobación rápida
En una for-comprehension de Option, ¿qué ocurre si un generador produce None?
Resumen
Ha aprendido el encadenamiento monádico con for-comprehensions:
- Funciona con cualquier tipo que tenga
mapyflatMap Optionse detiene al encontrarNoneEitheryTryse detienen cuando se produce un fallo y conservan la información del errorFutureencadena pasos asíncronos; inícielos pronto para ejecutarlos en paralelo- Todos los generadores deben compartir el mismo tipo de mónada
Preguntas frecuentes
¿La lección «Uso con Option y Future» es gratis?
Sí — el texto completo de «Uso con Option y Future» 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 «Uso con Option y Future»?
Encadenamiento monádico 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 4 de 4.
¿Cuánto tiempo toma la lección «Uso con Option y Future»?
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
- Desazucarado de for
- Filtrado con if
- Varios generadores
- Uso con Option y Future