使用(B => Future [C])函数将来[[A,B]]到[未来[A,C]]

Alb*_*urg 5 scala future either

我有一个Future[Either[A, B]]和一个功能提供一个Future[C]来自B.

我需要转变Future[Either[A, B]]Future[Either[A, C]].

是否有直接的方式获得Future[Either[A, C]]而不是Future[Either[A, Future[C]]]

我正在考虑这样的事情:

val eventuallyInitialValue: Future[Either[A, B]] = ???
val result: Future[Either[A, C]] = for {
  e: Either[A, B] <- initialValue
  c: C <- service.getValue(e.right)
} yield e.right.map(_ => c)
Run Code Online (Sandbox Code Playgroud)

它只是伪代码,因为service.getValue(e.right)不编译.这样做的正确方法是什么?

End*_*Neu 7

这就是我想出的:

type B = Int
type A = String
type C = Long
val eitherF: Future[Either[A, B]] = ???
def f(b: B): Future[C] = ???

val mapped: Future[Either[A, C]] = eitherF.flatMap {
  case Left(a) =>
    Future.successful(Left(a))
  case Right(b) =>
    f(b).map(Right(_))
}
Run Code Online (Sandbox Code Playgroud)

基本上你可以flatMap将来,然后如果它是一个左边只是返回成功,如果它是一个权利你可以应用未来并映射Right到它.


Łuk*_*asz 6

这是scalaz解决方案.请注意,它使用scalaz版本.

class A 
class B 
class C 

val initial: Future[A \/ B] = (new B).right.point[Future] 
val f: B => Future[C] = _ => (new C).point[Future] 

val result: Future[A \/ C] = (for {
                                e   <- EitherT(initial)
                                res <- EitherT(f(e).map(_.right))
                              } yield res).run
Run Code Online (Sandbox Code Playgroud)

它与@Ende Neu的基本相同,但匹配和重新包装隐藏在monad变换器中.