扁平化未来 [EitherT[Future, A, B]]

Flattening Future[EitherT[Future, A, B]]

如标题所述。

使用 EitherT[Future, A, B] 完成了许多操作。有时我想通过另一个具有签名 A => Future[C] 的操作向左或向右映射。另一种情况是 EitherT[Future, A, B] 映射到未来结果 Future[EitherT[Future, A, B]].

的结果

我怎样才能优雅地展平像这样的类型:

EitherT[Future, Future[A], Future[B]]Future[EitherT[Future, A, B]]

提前致谢。

在所有情况下,您都可以使用 EitherT#flatMap(或 EitherT#flatMapF),结合将某些值提升到 EitherT(或析取(\/)与 flatMapF).

  • B => F[C] 映射到 EitherT[F, A, B] 上:

    flatMap + 电梯

    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext.Implicits.global
    
    import scalaz._, Scalaz._
    
    def f(i: Int): Future[Double] = Future.successful(i.toDouble)
    val r = EitherT.right[Future, String, Int](Future.successful(1))
    
    r.flatMap(i => EitherT.right(f(i)))
    // or
    r.flatMapF(i => f(i).map(_.right))
    
  • EitherT[F, A, B] 上映射 A => F[C] :

    swap + flatMap + 提升

    def g(s: String): Future[Int] = Future.successful(s.length)
    
    val l = EitherT.left[Future, String, Int](Future.successful("error"))
    
    l.swap.flatMap(s => EitherT.right(g(s))).swap
    // or
    l.swap.flatMap(s => EitherT.left[Future, Int, Int](g(s)))
    // or
    l.swap.flatMapF(s => g(s).map(_.left))
    
  • A => Either[F, B, C] 映射到 F[A] :

    电梯 + flatMap

    def h(i: Int): EitherT[Future, String, Int] = 
      EitherT.right(Future.successful(i + 1))
    
    val fut = Future.successful(1)
    
    // mapping gives us Future[EitherT[Future, String, Int]]
    fut.map(h)                    
    
    // lifting to EitherT and flatMap gives us EitherT[Future, String, Int]
    EitherT.right(fut).flatMap(h)