Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Either[A, Future[B]] to Future[Either[A, B]]

Tags:

scala

future

Is there a way to convert a

Either[A, Future[B]] 

to a

Future[Either[A, B]]

I have in mind something like the Future.sequence method which converts from a List[Future] to a Future[List]

like image 764
Alina Boghiu Avatar asked Nov 23 '15 15:11

Alina Boghiu


3 Answers

Not sure there's an out of the box solution, this is what I came up with:

def foldEitherOfFuture[A, B](e: Either[A, Future[B]]): Future[Either[A, B]] =
  e match {
    case Left(s) => Future.successful(Left(s))
    case Right(f) => f.map(Right(_))
  }

In addition to catch eventual exception from the Future you can add a recover and map it to a Left:

case Right(f) => f.map(Right(_)).recover { case _ => Left(/** some error*/) }
like image 173
Ende Neu Avatar answered Oct 22 '22 01:10

Ende Neu


There is no api functional call to do that. I'd try something like this:

def getResult[A, B]: Either[A, Future[B]] = ???
val res = getResult.fold(fa = l => Future(Left(l)), fb = r => r.map(value => Right(value)))
like image 25
Dr. Vick Avatar answered Oct 22 '22 01:10

Dr. Vick


If you're using scalaz, you can just use sequenceU

import scala.concurrent.ExecutionContext.Implicits.global
import scalaz._
import Scalaz._

val x: Either[String, Future[Int]] = ???
val y: Future[Either[String, Int]] = x.sequenceU

Update (August 2019):

If you're using cats, use sequence:

import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global

val x: Either[String, Future[Int]] = ???
val y: Future[Either[String, Int]] = x.sequence
like image 3
dcastro Avatar answered Oct 22 '22 00:10

dcastro