Re: Proposal: make liftF a method of MonadFree
David Feuer <[email protected]> Fri, 16 Jul 2021 18:52:24 -0400
| Newsgroups | gmane.comp.lang.haskell.libraries |
|---|---|
| Message-ID | <CAMgWh9tt6wHxh1+09aSN-f8y7ZH_useoPc1k9R8t8S5+dt9upA@mail.gmail.com> |
Another flavor would be to leave liftF alone and add a method that does the same thing with a different name. This would preserve performance characteristics for instances like FT, for situations where the current implementation is faster. On Fri, Jul 16, 2021, 4:55 PM David Feuer <[email protected]> wrote: > We have > > class Monad m => MonadFree f m | m -> f where > wrap :: f (m a) -> m a > > liftF :: (Functor f, MonadFree f m) => f a -> m a > liftF = wrap . fmap pure > > I propose we change this to > > class Monad m => MonadFree f m | m -> f where > wrap :: f (m a) -> m a > > liftF :: f a -> m a > default liftF :: Functor f => f a -> m a > liftF = wrap . fmap pure > > and add a function > > defaultWrap :: MonadFree f m => f (m a) -> m a > defaultWrap = join . liftF > > 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. > > 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 > > newtype FT f m a = FT > { runFT :: forall r. (a -> m r) -> (forall x. (x -> m r) -> f x -> m r) > -> m r } > > for which > > liftF :: f a -> FT f m a > liftF fa = FT $ \pur bndf -> bndf pur fa > > Pull request at https://github.com/ekmett/free/pull/208 > _______________________________________________ Libraries mailing list [email protected] http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries