ZIO

sbt configuration

/***
libraryDependencies += "dev.zio" %% "zio" % "1.0.0-RC19-2"
*/

Usage

trait HasEnv {
  def env: Map[String, String]
}

def readEnv(name: String): zio.ZIO[HasEnv, Throwable, String] =
  zio.ZIO fromFunctionM { r =>
    zio.ZIO effect {
      r.env(name)
    }
  }
trait HasReadLn {
  def readLn(): String
}

val readLn: zio.ZIO[HasReadLn, Throwable, String] =
  zio.ZIO fromFunctionM { r =>
    zio.ZIO effect {
      r.readLn()
    }
  }
trait HasWrite {
  def write(output: String): Unit
}

def write(output: String): zio.ZIO[HasWrite, Throwable, Unit] =
  zio.ZIO fromFunctionM { r =>
    zio.ZIO effect {
      r.write(output)
    }
  }
val enProgram: zio.ZIO[HasReadLn with HasWrite, Throwable, Unit] =
  for {
    _    <- write("What's your name? ")
    name <- readLn
    _    <- write(s"Hello, ${name}!\n")
  } yield ()

val esProgram: zio.ZIO[HasReadLn with HasWrite, Throwable, Unit] =
  for {
    _    <- write("¿Cómo te llamas? ")
    name <- readLn
    _    <- write(s"¡Hola, ${name}!\n")
  } yield ()

val program: zio.ZIO[HasEnv with HasReadLn with HasWrite, Throwable, Unit] =
  for {
    lang <- readEnv("LANG")
    _    <- if (lang.startsWith("es")) {
              esProgram
            } else {
              enProgram
            }
  } yield ()
zio.Runtime.default.unsafeRun {
  program.provide {
    new HasEnv with HasReadLn with HasWrite {
      override val env: Map[String, String] = sys.env
      override def readLn(): String = scala.io.StdIn.readLine()
      override def write(output: String): Unit = print(output)
    }
  }
}

Demo

This file is literate Scala, and can be run using Codedown:

$ curl -s https://earldouglas.com/posts/effect-systems/zio.md |
  codedown scala > script.scala
$ LANG=es sbt -Dfile.encoding=UTF-8 -Dsbt.main.class=sbt.ScriptMain script.scala
¿Cómo te llamas? James
¡Hola, James!