Last active
December 4, 2019 12:16
-
-
Save neko-kai/7cba1eec2db102afd04f0d9fda222647 to your computer and use it in GitHub Desktop.
TRIO.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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