Skip to content

Instantly share code, notes, and snippets.

@dnaumenko
Last active February 11, 2020 12:44
Show Gist options
  • Save dnaumenko/451e2f084bddfb752f546d0adad73a04 to your computer and use it in GitHub Desktop.
Save dnaumenko/451e2f084bddfb752f546d0adad73a04 to your computer and use it in GitHub Desktop.
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)
}
class EnvConcurrent[Ctx](implicit concurrent: Concurrent[RIO[Context[Ctx], ?]]) extends EnvAsync with Concurrent[Env[Ctx, ?]] {
import cats.effect.Fiber.FiberOps
private def toFiber: FunctionK[RIO[Context[Ctx], ?], Env[Ctx, ?]] = new FunctionK[RIO[Context[Ctx], ?], Env[Ctx, ?]] {
override def apply[A](fa: RIO[Context[Ctx], A]): Env[Ctx, A] = ofZIO(fa)
}
override def start[A](fa: Env[Ctx, A]): Env[Ctx, cats.effect.Fiber[Env[Ctx, ?], A]] =
ofZIO(concurrent.start(fa.run).map(fiber => fiber.mapK(toFiber)))
override def race[A, B](fa: Env[Ctx, A], fb: Env[Ctx, B]): Env[Ctx, Either[A, B]] = ofZIO(concurrent.race(fa.run, fb.run))
override def racePair[A, B](fa: Env[Ctx, A], fb: Env[Ctx, B]): Env[Ctx, Either[(A, cats.effect.Fiber[Env[Ctx, ?], B]), (Fiber[Env[Ctx, ?], A], B)]] = {
ofZIO {
concurrent.racePair(fa.run, fb.run).map {
case Left((a, fiber)) => Left((a, fiber.mapK(toFiber)))
case Right((fiber, b)) => Right((fiber.mapK(toFiber), b))
}
}
}
override def cancelable[A](k: (Either[Throwable, A] => Unit) => CancelToken[Env[Ctx, ?]]): Env[Ctx, A] = {
ofZIO(concurrent.cancelable((k2: Either[Throwable, A] => Unit) => k(k2).run))
}
}
class EnvAsync[Ctx](implicit async: Async[RIO[Context[Ctx], ?]]) extends EnvSync with Async[Env[Ctx, ?]] {
override final def async[A](k: (Either[Throwable, A] => Unit) => Unit): Env[Ctx, A] = ofZIO(async.async(k))
override final def asyncF[A](k: (Either[Throwable, A] => Unit) => Env[Ctx, Unit]): Env[Ctx, A] = ofZIO {
async.asyncF((k2: Either[Throwable, A] => Unit) => k(k2).run)
}
override final def never[A]: Env[Ctx, A] = ofZIO(async.never)
}
class EnvSync[Ctx](implicit sync: Sync[RIO[Context[Ctx], ?]]) extends EnvBracket with Sync[Env[Ctx, ?]] {
override final def suspend[A](thunk: => Env[Ctx, A]): Env[Ctx, A] = ofZIO(sync.suspend(thunk.run))
override final def delay[A](thunk: => A): Env[Ctx, A] = ofZIO(sync.delay(thunk))
}
class EnvBracket[Ctx](implicit bracket: Bracket[RIO[Context[Ctx], ?], Throwable]) extends EnvMonadError with Bracket[Env[Ctx, ?], Throwable] {
override def bracketCase[A, B](acquire: Env[Ctx, A])(use: A => Env[Ctx, B])
(release: (A, ExitCase[Throwable]) => Env[Ctx, Unit]): Env[Ctx, B] = ofZIO {
bracket.bracketCase(acquire.run)(use(_).run) {
case (a, ec) => release(a, ec).run
}
}
}
class EnvMonadError[Ctx](implicit monadError: MonadError[RIO[Context[Ctx], ?], Throwable]) extends EnvMonad[Ctx] with MonadError[Env[Ctx, ?], Throwable] {
override def handleErrorWith[A](fa: Env[Ctx, A])(f: Throwable => Env[Ctx, A]): Env[Ctx, A] = ofZIO {
monadError.handleErrorWith(fa.run)(err => f(err).run)
}
override def raiseError[A](e: Throwable): Env[Ctx, A] = ofZIO {
monadError.raiseError(e)
}
}
class EnvMonad[Ctx](implicit monad: Monad[RIO[Context[Ctx], ?]]) extends cats.Monad[Env[Ctx, ?]] {
override def pure[A](x: A): Env[Ctx, A] = EnvCtx.pure(x)
override def map[A, B](fa: Env[Ctx, A])(f: A => B): Env[Ctx, B] = fa.map(f)
override def flatMap[A, B](fa: Env[Ctx, A])(f: A => Env[Ctx, B]): Env[Ctx, B] = fa.flatMap(f)
override def tailRecM[A, B](a: A)(f: A => Env[Ctx, Either[A, B]]): Env[Ctx, B] = ofZIO(monad.tailRecM(a)((a: A) => f(a).run))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment