给一个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)))但是,是否有一个高阶函数来完成这项工作呢?
我想使用sequence,但我没有外部类型的List
> :t sequence
sequence :: Monad m => [m a] -> m [a]发布于 2015-07-12 11:43:30
Haskell的sequence并不像它可能的那样通用,也不像Scalaz的那样通用(而且我假设您可以使用Scalaz的解决方案,因为您提到了sequence)。
Scalaz的sequence (以及Haskell的sequenceA in Data.Traversable)只要求外部类型的构造函数有一个Traverse实例-它不一定是一个列表。Option有一个Traverse实例,所以sequence在这里运行得很好:
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还为orZero提供了一个Option扩展方法,它只允许您编写x.orZero,因为Future[Option[Int]]的0是Future(None)。
实际上,在这种情况下,我可能会使用x.getOrElse(Future.successful(None)) --它稍微(可能无关紧要)更有表现力,但更重要的是,它和Scalaz选项一样清晰和简洁。
https://stackoverflow.com/questions/31364011
复制相似问题