scala - Nested For Expressions -


is there cleaner way, i.e. without nested for expressions, write following f, g, , doit functions?

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]] = {     x <- { <- f(100) } yield     y <- { <- g(x, 25) } yield } yield y 

i'm speculating use monad transformers, don't understand them.

if you're working types foo[qux[a]] both foo , qux monads , find you're writing lot of nested for-comprehensions, first thing should check scalaz (or cats) quxt monad transformer. allow work quxt[foo, a] values monadically single level of fors.

as other answers point out, don't need nested for-comprehensions in case given definition of g. i'm going assume want work values way inside future[either[string, ?]], without noisy g method, in case 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'd write doit.run future[either[string, int]]:

scala> doit.run.onsuccess { case e => println(e) } \/-(125) 

which same result implementation gives (except we've got scalaz's disjunction type).


Comments