background
get back the concurrent execution as a resource. That also is not completing the work somehow.
Resource
inside your biz logic
cats-mtl
, but what if you need to eventually provide a context and convert reader-like G
to a non-reader F
?
i usually use the former, and usually add
trait Train[F[_]] {
def toot(): F[Unit]
def mapK[G[_]](f: F ~> G): Train[G]
}
(cats-tagless can auto-generate these also)
Kleisli
vs. ApplicativeAsk
, that's one choice
F
s with different contexts.Lift
/Unlift
classes for conversion back and forth.ConnectionIO
and second to Kleisli[ConnectionIO, ...]
, both with its own lifts-unlifts
class BizLogic[F[_]](alg1: Alg1[F], alg2[Kleisli[F, Dependency]])
? because something like that would be difficult.
def withRequestId[F[_], G[_] : WithRun[*[_], F, RequestId[F]](routes: HttpRoutes[F]): HttpRoutes[G]
the former is more flexible, although it is likely that only Kleisli
has a WithRun
instance i'm guessing.
it's a familiarity issue, like you said. i think more folks would understand the Kleisli
version since it is more "concrete"
there's the evalMap(f: A => F[B]): Resource[F, A] => Resource[F, B] = _.flatMap(a => Resource.liftF(f(a)))
combinator that lifts the output of f
into an "inner" Resource
.
what about a different combinator that uses the first Resource
to create the next, where the first can be released: evalUse(f: A => F[B]): Resource[F, A] => Resource[F, B] = rfa => Resource.liftF(rfa.use(f))
?