Skip to content

Commit

Permalink
Make liftF a method of MonadFree
Browse files Browse the repository at this point in the history
This seems to work a bit better for things like `FT`.
  • Loading branch information
treeowl committed Jul 11, 2021
1 parent 41de25e commit ebf712f
Show file tree
Hide file tree
Showing 6 changed files with 11 additions and 10 deletions.
1 change: 0 additions & 1 deletion src/Control/Monad/Free.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ module Control.Monad.Free
( MonadFree(..)
, Free(..)
, retract
, liftF
, iter
, iterA
, iterM
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Free/Church.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ module Control.Monad.Free.Church
, hoistF
, foldF
, MonadFree(..)
, liftF
, cutoff
) where

Expand Down Expand Up @@ -157,6 +156,7 @@ instance MonadTrans F where

instance Functor f => MonadFree f (F f) where
wrap f = F (\kp kf -> kf (fmap (\ (F m) -> m kp kf) f))
liftF f = F (\kp kf -> kf (fmap kp f))

instance MonadState s m => MonadState s (F m) where
get = lift get
Expand Down
14 changes: 9 additions & 5 deletions src/Control/Monad/Free/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
----------------------------------------------------------------------------
module Control.Monad.Free.Class
( MonadFree(..)
, liftF
, wrapT
, defaultWrap
) where

import Control.Monad
Expand Down Expand Up @@ -109,6 +109,10 @@ class Monad m => MonadFree f m | m -> f where
wrap = join . lift . wrap . fmap return
#endif

-- | A version of lift that can be used with just a Functor for f.
liftF :: Functor f => f a -> m a
liftF = wrap . fmap return

instance (Functor f, MonadFree f m) => MonadFree f (ReaderT e m) where
wrap fm = ReaderT $ \e -> wrap $ flip runReaderT e <$> fm

Expand Down Expand Up @@ -151,13 +155,13 @@ instance (Functor f, MonadFree f m) => MonadFree f (ExceptT e m) where
-- instance (Functor f, MonadFree f m) => MonadFree f (EitherT e m) where
-- wrap = EitherT . wrap . fmap runEitherT

-- | A version of lift that can be used with just a Functor for f.
liftF :: (Functor f, MonadFree f m) => f a -> m a
liftF = wrap . fmap return

-- | A version of wrap for monad transformers over a free monad.
--
-- /Note:/ that this is the default implementation for 'wrap' for
-- @MonadFree f (t m)@.
wrapT :: (Functor f, MonadFree f m, MonadTrans t, Monad (t m)) => f (t m a) -> t m a
wrapT = join . lift . liftF

-- | An implementation of 'wrap' for 'MonadFree' instances that define 'liftF'.
defaultWrap :: (Functor f, MonadFree f m) => f (m a) -> m a
defaultWrap = join . liftF
1 change: 0 additions & 1 deletion src/Control/Monad/Trans/Free.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ module Control.Monad.Trans.Free
-- * The free monad
, Free, free, runFree
-- * Operations
, liftF
, iterT
, iterTM
, hoistFreeT
Expand Down
1 change: 0 additions & 1 deletion src/Control/Monad/Trans/Free/Ap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ module Control.Monad.Trans.Free.Ap
-- * The free monad
, Free, free, runFree
-- * Operations
, liftF
, iterT
, iterTM
, hoistFreeT
Expand Down
2 changes: 1 addition & 1 deletion src/Control/Monad/Trans/Free/Church.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ module Control.Monad.Trans.Free.Church
, iterM
-- * Free Monads With Class
, MonadFree(..)
, liftF
) where

import Control.Applicative
Expand Down Expand Up @@ -122,6 +121,7 @@ instance Monad (FT f m) where

instance MonadFree f (FT f m) where
wrap f = FT (\kp kf -> kf (\ft -> runFT ft kp kf) f)
liftF f = FT (\kp kf -> kf kp f)

instance MonadTrans (FT f) where
lift m = FT (\a _ -> m >>= a)
Expand Down

0 comments on commit ebf712f

Please sign in to comment.