加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用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))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读