1
votes

Given these three methods that return Future[Either[String,Int]]:

def greater(x:Int): Future[Either[String,Int]] = Future {
  if (x>0)
      Right(x)
  else
      Left("Is not greater")
}

def less(x:Int): Future[Either[String,Int]] = Future {
  if (x<0)
      Right(x)
  else
      Left("Is not less")
}

def zero(x:Int): Future[Either[String,Int]] = Future {
  if (x==0)
      Right(x)
  else
      Left("Is not zero")
}

The following method that invokes the three above throws a compilation error:

def evaluate(x:Int): Future[Either[String,Int]] = {
   val future = greater(x)
   future.flatMap { either =>
       either.right.flatMap { response => // <-- error in this line
           val future2 = less(response)
           future2.map { either2 =>   
             either2.right.map { response2 => zero(response2) }
          }
       }
   }
} 

The error:

type mismatch; found : scala.util.Either[String,Nothing] required: scala.concurrent.Future[Either[String,Int]]

How to fix the evaluate method?

1
So what is evaluate supposed to return after the future is done? For -1 is will be Left("Is not greater"), doesn't look like something useful. Or was it supposed to be another way round? - laughedelic
Is not useful, it's just an example to ask for the solution - ps0604

1 Answers

2
votes

Classic case of Monad transformers.

Use EitherT from cats

val result =
  for {
    a <- EitherT(greater(x))
    b <- EitherT(less(a))
    c <- EitherT(zero(b))
  } yield c

final value: result.value

Why EitherT?

Either is inside the another seemingly monad Future. So, EitherT can be used.