scala.concurrent.Future的替代实现?

时间:2015-07-28 20:37:11

标签: scala

给出两个Future[Option[Int]]

scala> val x: Future[Option[Int]] = Future.successful { None }
x: scala.concurrent.Future[Option[Int]] = scala.concurrent.impl.Promise$KeptPromise@39dcf4b0

scala> val y: Future[Option[Int]] = Future.successful { Some(55) }
y: scala.concurrent.Future[Option[Int]] = scala.concurrent.impl.Promise$KeptPromise@7ef2d7a6

有更清洁的方法来执行以下操作吗?

scala> def f[A](x: Future[Option[A]], 
                y: Future[Option[A]]): Future[Option[A]] = x.flatMap( _ match {
     |   case None => y
     |   case Some(_) => x
     | })
f: [A](x: scala.concurrent.Future[Option[A]], y: scala.concurrent.Future[Option[A]])scala.concurrent.Future[Option[A]]

我想过使用Alternative,但我不确定scala.concurrent.Future的这种实现:

>import Control.Applicative
> Nothing <|> Just 55
Just 55

3 个答案:

答案 0 :(得分:2)

您可以使用以下机制:

import scala.concurrent.{Await, duration, ExecutionContext, Future}
import duration.Duration
import ExecutionContext.Implicits.global

val f = Future.reduce(Seq(x, y))(_ orElse _)
Await.result(f, Duration.Inf) // Some(55)

如果选项数量不清楚,请使用Future.fold的零Option.empty[Int]

答案 1 :(得分:1)

如果你正在使用scalaz,你可以使用monad变换器,即使这样一个简单的例子有点过分。

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz.OptionT
import scalaz.std.scalaFuture.futureInstance

def f[A](x: Future[Option[A]],
         y: Future[Option[A]]): Future[Option[A]] = 
  OptionT(x).orElse(OptionT(y)).run

此外,您的功能的_ match部分不是必需的。

答案 2 :(得分:0)

在 Scala 2.13 中,您可以使用 zipWith 简化您的案例

%>%

或者在较低版本中使用zip

x.zipWith(y)(_ orElse _)
相关问题