Skip to content

Instantly share code, notes, and snippets.

object catz extends CatsInstance
abstract class CatsInstance {
import zio.interop.catz._
implicit def contextShift[Ctx]: ContextShift[Env[Ctx, ?]] = new EnvContextShift()
implicit def timer[Ctx]: EnvTimer[Ctx] = new EnvTimer
}
class EnvTimer extends Timer[Env[Ctx, ?]] {
import zio.interop.catz.implicits._
override def clock: Clock[Env[Ctx, ?]] = {
class EnvConcurrentEffect[Ctx](implicit concurrentEffect: ConcurrentEffect[RIO[Context[Ctx], ?]]) extends EnvConcurrent[Ctx] with ConcurrentEffect[Env[Ctx, ?]] {
override def runCancelable[A](fa: Env[Ctx, A])(cb: Either[Throwable, A] => effect.IO[Unit]): SyncIO[CancelToken[Env[Ctx, ?]]] = {
concurrentEffect.runCancelable(fa.run)(cb).map(ofZIO)
}
override def runAsync[A](fa: Env[Ctx, A])(cb: Either[Throwable, A] => effect.IO[Unit]): SyncIO[Unit] = {
concurrentEffect.runAsync(fa.run)(cb)
}
override def toIO[A](fa: Env[Ctx, A]): effect.IO[A] = concurrentEffect.toIO[A](fa.run)
case class EnvCtx[Ctx, +A](zio: RIO[Ctx, A]) extends Env[Ctx, A]
override def map[B](f: A => B): Env[Ctx, B] = EnvCtx(zio.map(f))
override def flatMap[B](f: A => Env[Ctx, B]): Env[Ctx, B] =
EnvCtx(zio.flatMap(a => f(a))) // compile error! f(a) should return ZIO
trait Env[Ctx, +A] {
def run: RIO[Ctx, A]
// basic transformations
def map[B](f: A => B): Env[Ctx, B]
def flatMap[B](f: A => Env[Ctx, B]): Env[Ctx, B]
def void: Env[Ctx, Unit] = map(_ => ())
}
override def run: RIO[Ctx, A] = zio
override def flatMap[B](f: A => Env[Ctx, B]): Env[Ctx, B] =
EnvCtx(zio.flatMap(a => f(a).run))
val program: Env[String, Unit] = for {
_ <- EnvCtx(ZIO.effect(println("Starting")))
_ <- EnvCtx(ZIO.effect(println("Finished")))
} yield ()
val runtime = Runtime({}, PlatformLive.Default)
val exit = runtime.unsafeRunSync(program.run.provide("Environment"))
println(exit)
private final class EnvCtx[Ctx, +A] (zio: RIO[Ctx, A]) extends Env[Ctx, A] {
override def run: RIO[Ctx, A] = zio
override def map[B](f: A => B) = ...
override def flatMap[B](f: A => Env[Ctx, B]) = ...
override def unsafeRunSync(env: Ctx): A = {
Exit.fromZIOExit(runtime.unsafeRunSync(zio.provide(env))) match {
case Exit.Success(value) => value
case Exit.Error(throwable) => throw throwable
case Exit.Termination(throwable) => throw throwable
}