Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Last active May 19, 2021 00:12
Show Gist options
  • Save yasuabe/8708ab28fe0c04399796827a6131c0eb to your computer and use it in GitHub Desktop.
Save yasuabe/8708ab28fe0c04399796827a6131c0eb to your computer and use it in GitHub Desktop.
main for composed behavior represented in module pattern with ZIO
import scalaz.zio.console.Console
import scalaz.zio._
// "org.scalaz" %% "scalaz-zio" % "1.0-RC3"
sealed trait AppError
case object NoValue extends AppError
trait Logger { val logger: Logger.Service }
object Logger {
trait Service { def info(line: String): UIO[Unit] }
trait Live extends Logger {
val logger: Service = new Service { // 敢えて SAM 無視
def info(line: String): UIO[Unit] = UIO.effectTotal(println(line))
}
}
def info(line: String): ZIO[Logger, Nothing, Unit] =
ZIO.accessM(_.logger info s"INFO: $line")
}
trait KVStore { val kvStore: KVStore.Service }
object KVStore {
trait Service { def valueOf(key: String): IO[AppError, String] }
trait Live extends KVStore {
private val dummy: Map[String, String] = Map("42" -> "Foo")
val kvStore: Service = new Service { // 敢えて SAM 無視
def valueOf(key: String): IO[AppError, String] =
IO.fromEither(dummy.get(key).toRight[AppError](NoValue))
}
}
def valueOf(key: String): ZIO[KVStore, AppError, String] =
ZIO.accessM(_.kvStore valueOf key)
}
import scalaz.zio.console._
import KVStore._
import Logger._
trait Env extends Console with Logger with KVStore
object Env extends Console.Live with Logger.Live with KVStore.Live
object Main extends App {
type AppType = Console with Logger with KVStore
val program: ZIO[AppType, AppError, Unit] = for {
key <- getStrLn.orDie
value <- valueOf(key)
_ <- info(s"$key -> $value")
} yield ()
def run(args: List[String]): ZIO[Environment, Nothing, Int] =
program.provide(Env).fold(
e => { println(e); -1 },
_ => 0
)
}
object MainSpec {
object testEnv extends Env {
val console: Console.Service[Any] = ???
val logger: Logger.Service = ???
val kvStore: KVStore.Service = ???
}
// Main.program.provide(testEnv) をテストするコードいろいろ
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment