使用Scalaz将选项列表转换为列表选项
发布时间:2020-12-16 09:43:11 所属栏目:安全 来源:网络整理
导读:我想将列表[选项[T]]转换为选项[列表[T]]。函数的签名类型是 def lo2ol[T](lo: List[Option[T]]): Option[List[T]] 预期的行为是将仅包含Somes的列表映射到Some中,其中包含元素Some中的元素列表。另一方面,如果输入列表至少有一个无,则预期的行为就是返回
我想将列表[选项[T]]转换为选项[列表[T]]。函数的签名类型是
def lo2ol[T](lo: List[Option[T]]): Option[List[T]] 预期的行为是将仅包含Somes的列表映射到Some中,其中包含元素Some中的元素列表。另一方面,如果输入列表至少有一个无,则预期的行为就是返回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()) 没有scalaz的示例实现将是: 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 } }} 解决方法
在Scalaz中有一个将List [Option [A]]转换成Option [List]的功能。这是序列。如果所有的元素都是“否”,如果所有元素都为“无”,并且某些[List [A]],如果所有元素都是Some,则可以得到“无”,您可以这么做:
import scalaz.syntax.traverse._ import scalaz.std.list._ import scalaz.std.option._ lo.sequence 考虑到存在Traverse [F]和Applicative [G](选项和列表)的实现,这种方法实际上将F [G [A]变为G [F [A]],这些实现满足两者并由这些导入提供)。 适用[选项]的语义是,如果选项列表中的任何元素为无,则序列也将为无。如果要获取所有“某些”值的列表,而不管其他值是否为“无”,您可以执行以下操作: lo flatMap (_.toList) 你可以推测,对于也形成Monoid的任何Monad(列表恰好是其中之一): import scalaz.syntax.monad._ def somes[F[_],A](x: F[Option[A]]) (implicit m: Monad[F],z: Monoid[F[A]]) = x flatMap (o => o.fold(_.pure[F])(z.zero)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |