Nested for understanding with futures

Given:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

def f: Future[Either[String, Int]] = Future { Right(100)}

def plus10(x: Int): Future[Either[String, Int]] = 
    Future { Right(x + 10) }

      

I am trying to combine Future[...]

together like this:

scala> for { 
     |  x <- f
     |  y <- for { a <- x.right } yield plus10(a)
     | } yield y
<console>:17: error: value map is not a member of Product with 
    Serializable with 
   scala.util.Either[String,scala.concurrent.Future[Either[String,Int]]]
        y <- for { a <- x.right } yield plus10(a)
                     ^

      

I expect to get: Future{Right(100)}

as a result, but I am getting the above compile time error.

Travis Brown gave a great answer on how to use Monad Transformers to fix my code here . However, how can I fix my code without Monad Transformers?

+1


source to share


2 answers


It turns out I can use Either#fold

:



 scala> for { 
     |  a <- f
     |  b <- a.fold(_ => Future { Left("bad") }, xx => plus10(xx) )
     | } yield b
res16: scala.concurrent.Future[Either[String,Int]] = 
     scala.concurrent.impl.Promise$DefaultPromise@67fc2aad

scala> res16.value
res17: Option[scala.util.Try[Either[String,Int]]] = 
          Some(Success(Right(110)))

      

+1


source


I was about to answer when yours showed up, but you can still look at this:

val res = for {
  x <- f
  y <- x.fold(x => Future{Left(x)}, plus10)
} yield y

      



It's a little more concise on the right side and holds the left side.

+1


source







All Articles