I am getting a compile error with this code. I have stripped it down to simplify it as much as possible. I am using cats EitherT
monad transformer here.
def foo(
id : String
): EitherT[Future, Err, Either[A, B]] =
for {
a <- f1(id)
} yield {
if (a > 2)
Left(A("Got an a"))
else {
for {
b <- f2() // THIS IS THE PROBLEM
} yield (Right(B("Got a B"))
}
}
The compiler is complaining about f2(). It has a return type of EitherT[Future,Err,C]
. The complier error I am getting is:
[error] found : cats.data.EitherT[Future,Err,scala.util.Right[Nothing,B]]
[error] required: Either[A,B]
[error] b <- f2()
I am not sure why it is complaining about this. I want to do the "if" check as a guard on the call to f2()
but I cannot as EitherT
does not have a withFilter method. Is there a better way to do this? Basic logic is, make call to f1()
. If the value of a > 2
do not call f2 but if it is not then call f2.
Try single flatMap
instead of nested for-comprehensions like so
case class A(v: String)
case class B(v: String)
case class C(v: String)
def f1(id: String): EitherT[Future, Err, Long] = EitherT.rightT(42)
def f2(): EitherT[Future, Err, C] = EitherT.rightT(C("cc"))
def foo(id : String): EitherT[Future, Err, Either[A, B]] =
f1(id).flatMap { a =>
if (a > 2)
EitherT.rightT(Left(A("Got an A")))
else
f2().map(b => Right(B("Got a B")))
}
foo("123").value.andThen(v => println(v))
which outputs
Success(Right(Left(A(Got an A))))
however I second Krzysztof's suggestion that EitherT[Future, Err, Either[A, B]]
models seems a bit unusual.