Created
October 19, 2022 03:44
-
-
Save rossabaker/c9c748449dd4061d38322b2d3a2b76c2 to your computer and use it in GitHub Desktop.
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
import cats.Monad | |
import cats.StackSafeMonad | |
import cats.data.Kleisli | |
import cats.data.OptionT | |
import cats.effect.MonadCancel | |
import cats.effect.Resource | |
final class Routes[F[_], A, B] private (val run: A => Resource[F, Option[B]]) { | |
def map[C](f: B => C): Routes[F, A, C] = | |
Routes(run(_).map(_.map(f))) | |
def flatMap[C](f: B => Routes[F, A, C]): Routes[F, A, C] = | |
Routes(a => run(a).flatMap { | |
case Some(b) => f(b).run(a) | |
case None => Resource.pure(None) | |
}) | |
def local[C](f: C => A): Routes[F, C, B] = | |
Routes((c: C) => run(f(c))) | |
def toKleisli(implicit F: MonadCancel[F, _]): Kleisli[Resource[OptionT[F, *], *], A, B] = | |
Kleisli(a => run(a).mapK(OptionT.liftK[F]).evalMap(OptionT.fromOption[F](_))) | |
} | |
object Routes { | |
def apply[F[_], A, B](run: A => Resource[F, Option[B]]): Routes[F, A, B] = | |
new Routes(run) | |
def pure[F[_], A, B](b: B) = | |
Routes((_: A) => Resource.pure[F, Option[B]](Some(b))) | |
def of[F[_], A, B](pf: PartialFunction[A, Resource[F, B]]): Routes[F, A, B] = | |
Routes(req => pf.lift(req) match { | |
case Some(resource) => resource.map(Some(_)) | |
case None => Resource.pure(None) | |
}) | |
def http[F[_]](pf: PartialFunction[Request[F], Resource[F, Response[F]]]): Routes[F, Request[F], Response[F]] = | |
of(pf) | |
implicit def monadInstance[F[_], A]: Monad[Routes[F, A, *]] = | |
new Monad[Routes[F, A, *]] with StackSafeMonad[Routes[F, A, *]] { | |
def pure[A](x: A) = | |
Routes.pure(x) | |
def flatMap[B, C](routes: Routes[F, A, B])(f: B => Routes[F, A, C]) = | |
routes.flatMap(f) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment