2017-01-01 5 views
1

Как упоминается в названии.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]]

Спасибо заранее.

ответ

2

Во всех ваших случаях вы можете использовать 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)) 
    
  • Картирование A => F[C] над EitherT[F, A, B]:

    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) 
    
Смежные вопросы