Saltar al contenido

¿Cómo combinar valores de opción en Scala?

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 Somes, 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *