Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MonadBase instance for FT and MonadBaseControl instances for FreeT and FT #156

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions free.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ library
transformers-base >= 0.4 && < 0.5,
template-haskell >= 2.7.0.0 && < 3,
exceptions >= 0.6 && < 0.11,
monad-control >= 1 && < 1.1,
containers < 0.7

if !impl(ghc >= 8.2)
Expand Down
36 changes: 36 additions & 0 deletions src/Control/Monad/Trans/Free.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
#if __GLASGOW_HASKELL__ >= 707
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
Expand Down Expand Up @@ -57,6 +58,8 @@ import Control.Monad (liftM, MonadPlus(..), ap, join)
import Control.Monad.Base (MonadBase(..))
import Control.Monad.Catch (MonadThrow(..), MonadCatch(..))
import Control.Monad.Trans.Class
import Control.Monad.Trans.Control (MonadTransControl(..), MonadBaseControl(..),
ComposeSt, defaultLiftBaseWith, defaultRestoreM)
import Control.Monad.Free.Class
import qualified Control.Monad.Fail as Fail
import Control.Monad.IO.Class
Expand Down Expand Up @@ -325,6 +328,39 @@ instance (Functor f, MonadBase b m) => MonadBase b (FreeT f m) where
liftBase = lift . liftBase
{-# INLINE liftBase #-}

{-
This instance must satisfy:
* liftWith . const . return = return
liftWith . const . return $ x
= lift $ (const $ return x) joinFreeT
= lift (return x)
= return x

* liftWith (const (m >>= f)) = liftWith (const m) >>= liftWith . const . f
liftWith (const m) >>= liftWith . const . f
= lift (const m (joinFreeT)) >>= \x -> lift $ const (f x) joinFreeT
= lift m >>= lift . f
= lift (m >>= f)
= lift (const (m >>= f) joinFreeT)
= liftWith (const (m >>= f))
* liftWith (\run -> run t) >>= restoreT . return = t
liftWith (\run -> run t) >>= restoreT . return
= lift (joinFreeT t) >>= lift . return >>= hoistFreeT (return . runIdentity)
= lift (joinFreeT t) >>= hoistFreeT (return . runIdentity)
= t
-}
instance (Traversable f) => MonadTransControl (FreeT f) where
type StT (FreeT f) a = Free f a
liftWith mkFreeT = lift $ mkFreeT joinFreeT
{-# INLINE liftWith #-}
restoreT mstt = lift mstt >>= hoistFreeT (return . runIdentity)
{-# INLINE restoreT #-}

instance (Traversable f, MonadBaseControl b m) => MonadBaseControl b (FreeT f m) where
type StM (FreeT f m) a = ComposeSt (FreeT f) m a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM

instance (Functor f, MonadReader r m) => MonadReader r (FreeT f m) where
ask = lift ask
{-# INLINE ask #-}
Expand Down
20 changes: 20 additions & 0 deletions src/Control/Monad/Trans/Free/Church.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}
#include "free-common.h"

-----------------------------------------------------------------------------
Expand Down Expand Up @@ -48,9 +49,12 @@ module Control.Monad.Trans.Free.Church
import Control.Applicative
import Control.Category ((<<<), (>>>))
import Control.Monad
import Control.Monad.Base (MonadBase(..))
import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
import Control.Monad.Identity
import Control.Monad.Trans.Class
import Control.Monad.Trans.Control (MonadTransControl(..), MonadBaseControl(..),
ComposeSt, defaultLiftBaseWith, defaultRestoreM)
import Control.Monad.IO.Class
import Control.Monad.Reader.Class
import Control.Monad.Writer.Class
Expand Down Expand Up @@ -156,6 +160,22 @@ instance (MonadIO m) => MonadIO (FT f m) where
liftIO = lift . liftIO
{-# INLINE liftIO #-}

instance MonadBase b m => MonadBase b (FT f m) where
liftBase = lift . liftBase
{-# INLINE liftBase #-}

instance (Traversable f) => MonadTransControl (FT f) where
type StT (FT f) a = F f a
liftWith mkFT = lift $ mkFT joinFT
{-# INLINE liftWith #-}
restoreT mstt = lift mstt >>= hoistFT (return . runIdentity)
{-# INLINE restoreT #-}

instance (MonadBaseControl b m, Traversable f) => MonadBaseControl b (FT f m) where
type StM (FT f m) a = ComposeSt (FT f) m a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM

instance (Functor f, MonadError e m) => MonadError e (FT f m) where
throwError = lift . throwError
{-# INLINE throwError #-}
Expand Down