Skip to content

Instantly share code, notes, and snippets.

View lforite's full-sized avatar
💯
TTT, types types types

Louis Forite lforite

💯
TTT, types types types
View GitHub Profile
case class Kleisli[F[_], A, B](run: A => F[B])
type Traceable[T] = CorrelationId ?=> T
//then
given cid: CorrelationId = ...
def f(x: Int): Traceable[Int] = ...
f(2) using cid // explicit argument
f(2) // argument is inferred
trait ServiceA {
def createA(a: EntityA): RIO[_]
}
trait ClientB {
def getB(bId: EntityBID): RIO[_]
}
case class ServiceA(clientB: ClientB) extends ServiceA {
override def createA(a: EntityA): RIO[_] = {
type RIO[A] = Kleisli[IO, CorrelationId, A]
case class HttpClientB(httpClient: HttpClient) extends ClientB {
def getB(bId: EntityBID): Klesli[IO, CorrelationId, EntityB] = Kleisli { cid =>
httpClient
.url(s"https://my-b-service-url.com/api/b-entity/bId")
.headers("X-Correlation-Id" -> cid)
.get()
}
}
case class ApiA(serviceA: ServiceA) {
def postA() = Route { request =>
val correlationId = request.headers("X-Correlation-Id")
.map(CorrelationId)
.getOrElse(CorrelationId.new)
serviceA.createA(request.body.decodeJson[EntityA])
.run(correlationId)
}
}
trait ServiceA {
def createA(a: EntityA): Klesli[IO, CorrelationId, _]
}
trait ClientB {
def getB(bId: EntityBID): Klesli[IO, CorrelationId, _]
}
case class ServiceA(clientB: ClientB) extends ServiceA {
override def createA(a: EntityA): Klesli[IO, CorrelationId, _] = {
trait Logger {
def info(msg: String): Kleisli[IO, CorrelationId, Unit] = Kleisli { cid =>
IO(underlyingLogger.info(s"[$cid] $msg"))
}
}
val context: String = "Kleisli, is that you ?"
val kleisli: Kleisli[IO, String, String] = Kleisli.ask()
val io: IO[String] = kleisli.run(context)
io.unsafeRunSync()
// returns string "Kleisli, is that you?
val context: String = "Kleisli, is that you ?"
val kleisli: Kleisli[IO, String, Unit] = Kleisli { (context: String) =>
IO(println(s"printing context: $context"))
}
val io: IO[Unit] = kleisli.run(context)
io.unsafeRunSync()
//"printing context: Kleisli, is that you?