给出两个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
答案 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 _)