http://hackage.haskell.org/package/free in Control.Monad.Free.Free allows one to get access to the "free monad" for any given Functor. It does not, however, have a MonadFix instance. Is this because such an instance cannot be written, or was it just left out?
If such an instance cannot be written, why not?
Consider the description of what
mfixdoes:The word "executes", in the context of
Free, means creating layers of theFunctor. Thus, "only once" means that in the result of evaluatingmfix f, the values held inPureconstructors must fully determine how many layers of the functor are created.Now, say we have a specific function
oncethat we know will always only create a singleFreeconstructor, plus however manyPureconstructors are needed to hold the leaf values. The output of 'once', then, will be only values of typeFree f athat are isomorphic to some value of typef a. With this knowledge, we can un-Freethe output ofoncesafely, to get a value of typef a.Now, note that because
mfixis required to "execute the action only once", the result ofmfix onceshould, for a conforming instance, contain no additional monadic structure thanoncecreates in a single application. Thus we can deduce that the value obtained frommfix oncemust also be isomorphic to a value of typef a.Given any function with type
a -> f afor someFunctorf, we can wrap the result with a singleFreeand get a function of typea -> Free f awhich satisfies the description ofonceabove, and we've already established that we can unwrap the result ofmfix onceto get a value of typef aback.Therefore, a conforming instance
(Functor f) => MonadFix (Free f)would imply being able to write, via the wrapping and unwrapping described above, a functionffix :: (Functor f) => (a -> f a) -> f athat would work for all instances ofFunctor.That's obviously not a proof that you can't write such an instance... but if it were possible,
MonadFixwould be completely superfluous, because you could just as easily writeffixdirectly. (And I suppose reimplement it asmfixwith aMonadconstraint, usingliftM. Ugh.)