We can define data Free f a = Pure a | Free (f (Free f a)) and so have Functor f => Monad (Free f).
If we define
data T f a b = R a | S b | T (f a (T f a b)) have we some analogous M so Profunctor f => M (T f a), where class Profunctor f where dimap :: (a -> b) -> (c -> d) -> f b c -> f a d?
I've been wondering ever since i noted Data.Comp.Term.Context and Free are isomorphic about a potential analog for Data.Comp.Param.Term.Context.
There's a more appropriate notion of making a free thing from a profunctor. Then we can work by analogy.
A free monoid, Y, generated by a set X is can be thought of as the solution to the equation "Y=1+XY". In Haskell notation that is
A free monad, M, generated by the functor F can be thought of as the solution to the equation "M=1+FM" where the product "FM' is the composition of functors. 1 is just the identity functor. In Haskell notation that is
Making something free from a profunctor P should look like a solution, A, to "A=1+PA". The product "PA" is the standard composition of profunctors. The 1 is the "identity" profunctor,
(->). So we getThis is also a profunctor:
If the profunctor is strong then so is the free version:
But what actually is
Free p? It's actually a thing called a pre-arrow. Restricting, free strong profunctors are arrows:Intuitively you can think of an element of a profunctor
P a bas taking ana-ish thing to ab-ish thing, the canonical example being given by(->).Free Pis an unevaluated chain of these elements with compatible (but unobservable) intermediate types.