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

scala – 选项[Future [Option [Int]]] => Future [Option [

发布时间:2020-12-16 18:05:46 所属栏目:安全 来源:网络整理
导读:给定选项[Future [Option [Int]]]: scala val x: Option[Future[Option[Int]]] = Some ( Future ( Some ( 10 ) ) )x: Option[scala.concurrent.Future[Option[Int]]] = Some(scala.concurrent.impl.Promise$DefaultPromise@446a1e84) 我想要Future [Option
给定选项[Future [Option [Int]]]:

scala> val x: Option[Future[Option[Int]]] = Some ( Future ( Some ( 10 ) ) )
x: Option[scala.concurrent.Future[Option[Int]]] = 
    Some(scala.concurrent.impl.Promise$DefaultPromise@446a1e84)

我想要Future [Option [Int]].

我可以模式匹配(或使用Option#getOrElse):

scala> x match { 
     |   case Some(f) => f
     |   case None    => Future { None } 
     | }
res6: scala.concurrent.Future[Option[Int]] =  
     scala.concurrent.impl.Promise$DefaultPromise@446a1e84

scala> res6.value
res7: Option[scala.util.Try[Option[Int]]] = Some(Success(Some(10)))

但是,是否有更高阶的功能可以完成这项工作?

我想过使用序列,但我没有外部类型的List:

> :t sequence
sequence :: Monad m => [m a] -> m [a]

解决方法

Haskell的序列并不像它可能那样通用,或者像Scalaz那样通用(我假设你提到Scalaz解决方案,因为你提到了序列).

Scalaz的序列(以及Data.Traversable中的Haskell的sequenceA)只要求外部类型构造函数具有Traverse实例 – 它不一定必须是列表.选项有一个Traverse实例,所以序列在这里工作得很好:

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._,Scalaz._

def collapse(x: Option[Future[Option[Int]]]): Future[Option[Int]] =
  x.sequence.map(_.flatten)

Scalaz还为Option提供了一个orZero扩展方法,它允许你只写x.orZero,因为Future [Option [Int]]的零是Future(None).

我实际上可能会使用x.getOrElse(Future.successful(None)),但在这种情况下 – 它稍微(可能是无关紧要)更高性能,但更重要的是它与Scalaz选项一样清晰且几乎简洁.

(编辑:李大同)

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

    推荐文章
      热点阅读