<div dir="auto">We have<div dir="auto"><br></div><div dir="auto">class Monad m => MonadFree f m | m -> f where</div><div dir="auto">  wrap :: f (m a) -> m a</div><div dir="auto"><br></div><div dir="auto">liftF :: (Functor f, MonadFree f m) => f a -> m a</div><div dir="auto">liftF = wrap . fmap pure</div><div dir="auto"><br></div><div dir="auto">I propose we change this to</div><div dir="auto"><br></div><div dir="auto">class Monad m => MonadFree f m | m -> f where</div><div dir="auto">  wrap :: f (m a) -> m a</div><div dir="auto"><br></div><div dir="auto">  liftF :: f a -> m a</div><div dir="auto"><div dir="auto" style="font-family:sans-serif">  default liftF :: Functor f => f a -> m a</div><div dir="auto" style="font-family:sans-serif">  liftF = wrap . fmap pure</div><div dir="auto" style="font-family:sans-serif"><br></div><div dir="auto" style="font-family:sans-serif">and add a function</div><div dir="auto" style="font-family:sans-serif"><br></div><div dir="auto" style="font-family:sans-serif">defaultWrap :: MonadFree f m => f (m a) -> m a</div><div dir="auto" style="font-family:sans-serif">defaultWrap = join . liftF</div><div dir="auto" style="font-family:sans-serif"><br></div><div dir="auto" style="font-family:sans-serif">This change is not strictly backwards compatible. Some instances might, hypothetically, have to add a Functor constraint. For example, the classic Control.Monad.Free and Control.Monad.Trans.Free would need them. However, those instances already have (currently redundant) Functor constraints, so that doesn't seem like a big deal.</div><div dir="auto" style="font-family:sans-serif"><br></div><div dir="auto" style="font-family:sans-serif">An alternative would be to hew more strictly to backwards compatibility by placing a Functor f constraint on liftF. This seems a bit sad for "freer" instances that don't need it. For example, we have</div><div dir="auto" style="font-family:sans-serif"><br></div><div dir="auto" style=""><div dir="auto" style=""><font face="sans-serif">newtype FT f m a =</font> <span style="font-family:sans-serif">FT</span></div><div dir="auto" style=""><span style="font-family:sans-serif">  {</span> <span style="font-family:sans-serif">runFT :: forall r. (a -> m r) -> (forall x. (x -> m r) -> f x -> m r) -> m r }</span></div><div style="font-family:sans-serif" dir="auto"><br></div><div style="font-family:sans-serif" dir="auto">for which</div><div style="font-family:sans-serif" dir="auto"><br></div><div style="font-family:sans-serif" dir="auto">liftF :: f a -> FT f m a</div><div style="font-family:sans-serif" dir="auto">liftF fa = FT $ \pur bndf -> bndf pur fa</div><div style="font-family:sans-serif" dir="auto"><br></div><div style="font-family:sans-serif" dir="auto">Pull request at <a href="https://github.com/ekmett/free/pull/208">https://github.com/ekmett/free/pull/208</a></div></div></div></div>