Last active
January 14, 2021 12:49
-
-
Save ShahOdin/3286bc06989733d44cc973087e48d71f 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
object Foo extends App { | |
import cats.data.Kleisli | |
import cats.Functor | |
import cats.effect.IO | |
import cats.syntax.functor._ | |
import cats.syntax.flatMap._ | |
type TraceyId = String | |
type Tracey[F[_], A] = Kleisli[F, TraceyId, A] | |
type TraceyIO[A] = Tracey[IO, A] | |
type Request = String | |
import cats.tagless.{FunctorK, Derive} | |
import cats.~> | |
trait TraceyIdGenerator[F[_]] { | |
def generate: F[TraceyId] | |
} | |
object TraceyIdGenerator { | |
implicit val io: TraceyIdGenerator[IO] = new TraceyIdGenerator[IO] { | |
override def generate: IO[TraceyId] = IO.pure("beaker") | |
} | |
} | |
implicit class RequestOps[F[_]](request: Request) { | |
def traceIdOrCreate[F[_]](implicit generator: TraceyIdGenerator[F]): F[TraceyId] = { | |
val _ = request | |
generator.generate | |
} | |
} | |
implicit class ops[C[_[_]]: FunctorK, F[_]](client: C[Tracey[F, *]]) { | |
def usingGenerator(implicit gen: TraceyIdGenerator[F], F: Functor[F]): Kleisli[F, Request, C[F]] = | |
Kleisli[F, Request, TraceyId](_.traceIdOrCreate).map(id => FunctorK[C].mapK(client)(λ[Tracey[F, *] ~> F](_.run(id)))) | |
} | |
trait Foo[F[_]] { | |
def foo: F[Unit] | |
} | |
object Foo { | |
val traceIoClient: Foo[TraceyIO] = new Foo[TraceyIO] { | |
override def foo: TraceyIO[Unit] = Kleisli[IO, TraceyId, Unit](tracey => IO(println(s"Called Foo with $tracey"))) | |
} | |
implicit val functorK: FunctorK[Foo] = Derive.functorK[Foo] | |
} | |
trait Bar[F[_]] { | |
def bar: F[Unit] | |
} | |
object Bar { | |
val ioClient: Bar[IO] = new Bar[IO] { | |
override def bar: IO[Unit] = IO(println(s"Called Bar")) | |
} | |
} | |
trait Route[F[_]] { | |
def respond(request: Request): F[Unit] | |
} | |
object Route { | |
def apply[F[_]: Monad](getClient: Kleisli[F, Request, Foo[F]], bar: Bar[F]): Route[F] = (request: Request) => | |
for { | |
foo <- getClient(request) | |
_ <- bar.bar | |
_ <- foo.foo | |
} yield () | |
} | |
val foo: Kleisli[IO, Request, Foo[IO]] = Foo.traceIoClient.usingGenerator | |
val bar = Bar.ioClient | |
Route[IO](foo, bar).respond("???").unsafeRunSync() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
actually what the auxilary method does can be contained in
simplify
so simplfiy returnsF[Client[F]]
in the first place. will update