Nested expressions
Is there a cleaner way i.e. without nested for expressions
, write the following functions f
, g
and doIt
?
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def f(x: Int): Future[Either[String, Int]] = Future(Right(100))
def g(x: Either[String, Int], y: Int): Future[Either[String, Int]] =
Future { x match {
case Right(i) => Right(i + y)
case Left(err) => Left(err)
}}
def doIt: Future[Either[String, Int]] = for {
x <- for { a <- f(100) } yield a
y <- for { a <- g(x, 25) } yield a
} yield y
I am contemplating that I can use Monad Transformers, but I do not understand them.
source to share
If you work with these types of as Foo[Qux[A]]
, where both Foo
and Qux
are monads, and you will find that writing many nested for
-posobstvy, the first thing you need to do is check Scalaz (or cats ) to QuxT
monad transformer. This will allow you to work with values QuxT[Foo, A]
monadically with one level for
s.
As the other answers for
suggest , you don't actually need nested- manuals in your case given your definition g
. I assume you want to work with values ββentirely internally Future[Either[String, ?]]
, without a noisy method g
, in which case you want EitherT[Future, String, Int]
:
import scalaz._, Scalaz._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def f(x: Int): EitherT[Future, String, Int] =
EitherT.fromEither(Future[Either[String, Int]](Right(100)))
// Or just:
// def f(x: Int): EitherT[Future, String, Int] = EitherT.right(Future(100))
def doIt: EitherT[Future, String, Int] = f(100).map(_ + 25)
Eventually you would write doIt.run
to get Future[Either[String, Int]]
:
scala> doIt.run.onSuccess { case e => println(e) }
\/-(125)
This is the same output that your implementation gives (except that we have a Scalaz splitting type).
source to share