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. In the code you’ll see that I convert each Either into a ZIO in each line of the for-expression.

Here’s the Scala/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

A better ZIO/Either example

One other thing I have should have shown in this example is that the only reason you’d convert these Either values into ZIO values in this specific example is if you wanted to use other ZIO values in the for expression, like this:

for
    a <- ZIO.fromEither(makeInt("1"))
    b <- ZIO.fromEither(makeInt("uh oh"))
    c <- ZIO.fromEither(makeInt("3"))
    d <- ZIO.succeed(42)   // some other ZIO value here
yield
    a + b + c

If you don’t need to mix another ZIO value into the for-expression, Either values work just fine in for-expressions by themselves:

for
    a <- makeInt("1")
    b <- makeInt("uh oh")
    c <- makeInt("3")
yield
    a + b + c

In this example, each makeInt call returns an Either value, and this works (as I have shown in other examples on this website).

Summary: ZIO, Either, and for-expressions

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.

Also, for more information on this topic, see my free video on How the Scala Either type relates to the ZIO type.