ZIO 2: Using Either with ZIO in a Scala for-expression

As a little note here today, here’s an example of how to use a Scala Either inside a for-expression when using ZIO 2. Specifically I convert each Either into a ZIO in each line of the for-expression.

Here’s the ZIO code:

//> using scala "3"
//> using lib "dev.zio::zio::2.1.0"
package zio_either_test

import zio.*
import zio.Console.*
import java.io.IOException
import scala.util.control.Exception.*

def makeInt(s: String): Either[Throwable, Int] = 
    allCatch.either(s.toInt)

object ZioEitherInForExpr extends ZIOAppDefault:

    val blueprint: ZIO[Any, Throwable, Int] =
        for
            a <- ZIO.fromEither(makeInt("1"))
            b <- ZIO.fromEither(makeInt("uh oh"))
            c <- ZIO.fromEither(makeInt("3"))
        yield
            a + b + c

    val run = blueprint.foldZIO(
        failure => printLineError(s"FAILURE = $failure"),
        success => printLine(     s"SUCCESS = $success")
    )

Notice that makeInt returns an Either, but I want to use ZIO values inside the for-expression, so I convert each Either into a ZIO with ZIO.fromEither.

When the string in the second line of the for-expression is "uh oh", I see this output when I run this ZIO application:

$ scala-cli ZioEitherForExpression.scala 
FAILURE = java.lang.NumberFormatException: For input string: "uh oh"

As I have noted in other articles and videos, that’s because the for-expression short-circuits on that line of code.

But if I change that "uh oh" to a "2", I see this output instead:

$ scala-cli ZioEitherForExpression.scala 
SUCCESS = 6

In summary, if you wanted to see how to use ZIO 2 along with Either and ZIO values in a Scala for-expression, I hope this little example is helpful. Also note that the same technique can be used with Scala Option and Try values, almost exactly as shown with the Either values here.