Skip to content

Instantly share code, notes, and snippets.

@neko-kai
Last active December 4, 2019 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neko-kai/7cba1eec2db102afd04f0d9fda222647 to your computer and use it in GitHub Desktop.
Save neko-kai/7cba1eec2db102afd04f0d9fda222647 to your computer and use it in GitHub Desktop.
TRIO.scala
trait TRIO[F[-_, +_, +_]] {
def pure[A](a: A): F[Any, Nothing, A]
def fail[E](e: E): F[Any, E, Nothing]
def flatMap[R1, E1, A, R2 <: R1, E2 >: E1, B](fa: F[R1, E1, A])(fab: A => F[R2, E2, B]): F[R2, E2, B]
def catchAll[R1, E1, A, R2 <: R1, E2, A2 >: A](fa: F[R1, E1, A])(h: E1 => F[R2, E2, A2]): F[R2, E2, A2]
def bracket[R, E, A, B](acquire: F[R, E, A], release: A => F[R, Nothing, Unit], use: A => F[R, E, B]): F[R, E, B]
}
object TRIO {
def F[F[-_, +_, +_]](implicit F: TRIO[F]): F.type = F
type F2[F[+_, +_]] = { type l[-R, +E, +A] = F[E, A] }
type TBIO[F[+_, +_]] = TRIO[F2[F]#l]
implicit val zioTrio: TRIO[F2[IO]#l] = new TRIO[F2[IO]#l] {
override def pure[A](a: A): IO[Nothing, A] =
IO.succeed(a)
override def fail[E](e: E): IO[E, Nothing] =
IO.fail(e)
override def flatMap[R1, E1, A, R2 <: R1, E2 >: E1, B](fa: IO[E1, A])(fab: A => IO[E2, B]): IO[E2, B] =
fa.flatMap(fab)
override def catchAll[R1, E1, A, R2 <: R1, E2, A2 >: A](fa: IO[E1, A])(h: E1 => IO[E2, A2]): IO[E2, A2] =
fa.catchAll(h)
override def bracket[R, E, A, B](acquire: IO[E, A], release: A => IO[Nothing, Unit], use: A => IO[E, B]): IO[E, B] =
IO.bracket(acquire)(release)(use)
}
object syntax {
implicit final class FlatMap3[F[- _, + _, + _] : TRIO, -R, +E, +A](private val fa: F[R, E, A]) {
def flatMap[R2 <: R, E2 >: E, B](fab: A => F[R2, E2, B]): F[R2, E2, B] =
F[F].flatMap[R, E, A, R2, E2, B](fa)(fab)
def map[B](f: A => B): F[R, E, B] = flatMap(a => F[F].pure(f(a)))
}
implicit final class FlatMap2[F[+ _, + _] : TBIO, +E, +A](private val fa: F[E, A]) {
def flatMap[E2 >: E, B](fab: A => F[E2, B]): F[E2, B] =
F[F2[F]#l].flatMap[Any, E, A, Any, E2, B](fa)(fab)
def map[B](f: A => B): F[E, B] = flatMap(a => F[F2[F]#l].pure(f(a)))
}
}
}
import TRIO.F
import TRIO.syntax._
def nothing[F[+_, +_]: TBIO]: F[Nothing, Unit] = F.pure(())
def throwable[F[+_, +_]: TBIO]: F[Throwable, Unit] = nothing
def runtime[F[+_, +_]: TBIO]: F[RuntimeException, Unit] = nothing
def test[F[+_, +_]: TBIO]: F[Throwable, Int] =
for {
x <- F.pure(2)
_ <- nothing
_ <- runtime
_ <- throwable
y <- F.pure(7)
} yield x + y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment