Quiero transformar un List[Option[T]]
en un Option[List[T]]
. El tipo de firma de la función esConvertir una lista de opciones a una opción de lista usando Scalaz
def lo2ol[T](lo: List[Option[T]]): Option[List[T]]
El comportamiento esperado es mapear una lista que contiene sólo Some
s en un Some
que contienen una lista de los elementos dentro de los elementos Some
's. Por otro lado, si la lista de entrada tiene al menos un None
, el comportamiento esperado es simplemente devolver None
. Por ejemplo:
scala> lo2ol(Some(1) :: Some(2) :: Nil)
res10: Option[List[Int]] = Some(List(1, 2))
scala> lo2ol(Some(1) :: None :: Some(2) :: Nil)
res11: Option[List[Int]] = None
scala> lo2ol(Nil : List[Option[Int]])
res12: Option[List[Int]] = Some(List())
una implementación de ejemplo, y sin scalaz, sería:
def lo2ol[T](lo: List[Option[T]]): Option[List[T]] = {
lo.foldRight[Option[List[T]]](Some(Nil)){(o, ol) => (o, ol) match {
case (Some(x), Some(xs)) => Some(x :: xs);
case _ => None : Option[List[T]];
}}}
Recuerdo haber visto en alguna parte un ejemplo similar, pero usando Scalaz para simplificar el código. ¿Cómo se vería?
Una versión ligeramente más sucinta, utilizando Scala2.8 PartialFunction.condOpt
, pero aún sin Scalaz:
import PartialFunction._
def lo2ol[T](lo: List[Option[T]]): Option[List[T]] = {
lo.foldRight[Option[List[T]]](Some(Nil)){(o, ol) => condOpt(o, ol) {
case (Some(x), Some(xs)) => x :: xs
}
}}
Pero si solo desea los valores 'Some' de' List [Option [A]] ', ya no necesita' Option'. Tendrás una lista vacía o una lista no vacía de 'A'. – Apocalisp
En realidad, quiero obtener 'None' en caso de que alguno de los elementos sea' None', entonces 'sequence' es exactamente lo que solicité. Trataré de editar la pregunta para aclarar el requisito. –
No puedo hacer que 'lo.sequence' funcione. Usando scala-2.8.0.Beta1 y scalaz-core_2.8.0.Beta1-5.0.1-SNAPSHOT.jar, si ingreso 'def lo2ol [T] (lo: List [Option [T]]): Option [List [ T]] = lo.sequence', obtengo ': 10: error: expansión implícita divergente para el tipo scalaz.Applicative [N]' –