Я хочу преобразовать List[Option[T]]
в Option[List[T]]
. Тип подписи функции
def lo2ol[T](lo: List[Option[T]]): Option[List[T]]
Ожидаемое поведение - сопоставить список, содержащий только Some
, в Some
, содержащий список элементов внутри элементов Some
. С другой стороны, если в списке ввода есть хотя бы один None
, ожидаемое поведение - просто вернуть None
. Например:
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())
Пример реализации без скаляза:
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]];
}}}
Я помню, где-то был похожий пример, но с помощью Scalaz для упрощения кода. Как это будет выглядеть?
Несколько более краткий вариант, используя Scala2.8 PartialFunction.condOpt
, но все же без 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
}
}}