Skip to content

Instantly share code, notes, and snippets.

@ShahOdin
Last active January 14, 2021 12:49
Show Gist options
  • Save ShahOdin/3286bc06989733d44cc973087e48d71f to your computer and use it in GitHub Desktop.
Save ShahOdin/3286bc06989733d44cc973087e48d71f to your computer and use it in GitHub Desktop.
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()
}
@ShahOdin
Copy link
Author

ShahOdin commented Jan 14, 2021

actually what the auxilary method does can be contained in simplify so simplfiy returns F[Client[F]] in the first place. will update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment