Posterior a de nuestra prolongada compilación de datos hemos podido solucionar esta incógnita que pueden tener algunos de nuestros lectores. Te regalamos la respuesta y deseamos que sea de mucha ayuda.
Solución:
scala> val (x, y) = (Some(4), Some(9))
x: Some[Int] = Some(4)
y: Some[Int] = Some(9)
scala> def f(x: Int, y: Int) = Math.max(x, y)
f: (x: Int,y: Int)Int
scala> for x0 <- x; y0 <- y yield f(x0, y0)
res26: Option[Int] = Some(9)
scala> val x = None
x: None.type = None
scala> for x0 <- x; y0 <- y yield f(x0, y0)
res27: Option[Int] = None
@RahulGLa respuesta de explota el hecho de que Option
es una mónada (aunque no hay ningún tipo para representar esto en la biblioteca de Scala). El compilador expande el for
comprensión a lo siguiente:
def a: Option[Int]
def b: Option[Int]
val calc: Option[Int] = a flatMap aa => b map bb => aa + bb
También puede tratarlo como un funtor aplicativo, con la ayuda de Scalaz:
import scalaz._
import Scalaz._
def a: Option[Int]
def b: Option[Int]
val calc: Option[Int] = (a ⊛ b) _ + _
A key diferencia es que en el cálculo monádico, un fallo (es decir, None
) de cálculo a
cortocircuita la evaluación. En el estilo aplicativo, tanto a
y b
son evaluados, y si ambos son Some
s, la función pura se llama. También puedes ver que en el cálculo monádico, el valor aa
podría haber sido utilizado en el cálculo b
; en la versión aplicativa, b
no puede depender del resultado de a
.
Tengo una versión un poco más antigua de escalaz que retrónimo pero lo siguiente me funciona como ejemplo y es generalizable para el caso en el que tiene 3 tipos T, U, V
y no solo uno:
def main(args: Array[String]) *
Entonces puedo agregar:
val opt3 = none[Int]
val res2 = (opt1 <|*|> opt3).map(f.tupled)
println(res2) //None
Calificaciones y reseñas
No se te olvide recomendar este ensayo si si solucionó tu problema.