Open notxcain opened 5 years ago
Definitely interesting to me. I also remember seeing mentioning of interest in this. A PR would be great!
I'm not sure I fully understand ReifiedInvocation
but Invocation
can be seen as a specialization of Program
:) see here: https://github.com/typelevel/cats-tagless/blob/master/core/src/main/scala/cats/tagless/optimize/Program.scala
@LukaJCB Program
is fine as a replacement for Invocation
if there is a constraint that exists for all F[_]
, e.g. some Unconstrained[F[_]]
Another example for ReifiedInvocations
is this:
def router[K, F[_]: Concurrent, M[_[_]]: ReifiedInvocations: FunctorK](load: K => F[M[F]): F[K => M[F]] =
MVar[F].of(Map.empty[K, M[F]]).map { instancesVar =>
{ key: K =>
ReifiedInvocations[M].invocations.mapK {
new (Invocation[M, ?] ~> F) {
override def apply[A](invocation: Invocation[M, A]): F[A] =
for {
instances <- instancesVar.take
mf <- instances.get(key) match {
case Some(mf) => instancesVar.put(instances) >> mf.pure[F]
case None =>
load(key).flatMap { mf =>
instancesVar.put(instances.updated(key, mf)).as(mf)
}
}
a <- invocation.invoke(mf)
} yield a
}
}
}
}
So it allows you to transform some M[_[_]]
instance, even if you don't have it yet.
In other words ReifiedInvocations#invocations
makes it possible to create an instance that does nothing other than captures method invocations, which you can run later against some other instance.
I want to drop a support of Liberator in favour of
cats-tagless
. But there are two very useful types that I need. And I think they may be a good fit forcats-tagless
.Invocation[M[_[_]], A]
allows to encode some call of
M[F]
resulting inF[A]
it's like a dual of Free algebra base functor.ReifiedInvocations[M[_[_]]]
type classallows to create an instance of
M[Invocation[M, ?]]
that is very useful for transformation of tagless algebras (see Aecor). There is also a macro for its derivation.If you find this interesting I will send a PR.
P.S. One interesting intuition is that
M[F]
is a collection of appliedF[_]
indexed byInvocation[M, A]
:)