module Control.Distributed.Process.Lifted.Class where
import Control.Distributed.Process (Process)
import Control.Distributed.Process.MonadBaseControl ()
import qualified Control.Monad.State.Strict as StateS
import Control.Monad.Trans (MonadIO,
lift)
import Control.Monad.Trans.Control
import Control.Monad.Base (MonadBase(..))
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid ( Monoid )
#endif
import Control.Monad.Trans.Identity (IdentityT)
import Control.Monad.Trans.List (ListT)
import Control.Monad.Trans.Maybe (MaybeT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.State (StateT)
import Control.Monad.Trans.Writer (WriterT)
import Control.Monad.Trans.RWS (RWST)
import Control.Monad.Trans.Except (ExceptT)
import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST)
import qualified Control.Monad.Trans.State.Strict as Strict (StateT)
import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT)
class (Monad m, MonadIO m, MonadBase IO m, MonadBaseControl IO m) => MonadProcess m where
liftP :: Process a -> m a
class (MonadProcess m) => MonadProcessBase m where
type StMP m a :: *
liftBaseWithP :: (RunInBaseP m -> Process a) -> m a
restoreMP :: StMP m a -> m a
type RunInBaseP m = forall a. m a -> Process (StMP m a)
type ComposeStP t m a = StMP m (StT t a)
type RunInBaseDefaultP t m = forall a. t m a -> Process (ComposeStP t m a)
defaultLiftBaseWithP :: (MonadTransControl t, MonadProcessBase m)
=> (RunInBaseDefaultP t m -> Process a) -> t m a
defaultLiftBaseWithP f= liftWith $ \run ->
liftBaseWithP $ \runInBase ->
f $ runInBase . run
defaultRestoreMP :: (MonadTransControl t, MonadProcessBase m)
=> ComposeStP t m a -> t m a
defaultRestoreMP = restoreT . restoreMP
controlP :: MonadProcessBase m => (RunInBaseP m -> Process (StMP m a)) -> m a
controlP f = liftBaseWithP f >>= restoreMP
liftBaseDiscardP :: MonadProcessBase m => (Process () -> Process a) -> m () -> m a
liftBaseDiscardP f m = liftBaseWithP $ \runInBase -> f $ StateS.void $ runInBase m
instance MonadProcess Process where
liftP = id
instance MonadProcessBase Process where
type StMP Process a = a
liftBaseWithP f = f id
restoreMP = return
#define LIFTP(T) \
instance (MonadProcess m) => MonadProcess (T m) where liftP = lift . liftP \
LIFTP(IdentityT)
LIFTP(MaybeT)
LIFTP(ListT)
LIFTP(ReaderT r)
LIFTP(Strict.StateT s)
LIFTP( StateT s)
LIFTP(ExceptT e)
#undef LIFTP
#define LIFTP(CTX, T) \
instance (CTX, MonadProcess m) => MonadProcess (T m) where liftP = lift . liftP \
LIFTP(Monoid w, Strict.WriterT w)
LIFTP(Monoid w, WriterT w)
LIFTP(Monoid w, Strict.RWST r w s)
LIFTP(Monoid w, RWST r w s)
#define BODY(T) { \
type StMP (T m) a = ComposeStP (T) m a; \
liftBaseWithP = defaultLiftBaseWithP; \
restoreMP = defaultRestoreMP; \
; \
}
#define TRANS( T) \
instance (MonadProcessBase m) => MonadProcessBase (T m) where BODY(T)
#define TRANS_CTX(CTX, T) \
instance (CTX, MonadProcessBase m) => MonadProcessBase (T m) where BODY(T)
TRANS(IdentityT)
TRANS(MaybeT)
TRANS(ListT)
TRANS(ReaderT r)
TRANS(Strict.StateT s)
TRANS( StateT s)
TRANS(ExceptT e)
TRANS_CTX(Monoid w, Strict.WriterT w)
TRANS_CTX(Monoid w, WriterT w)
TRANS_CTX(Monoid w, Strict.RWST r w s)
TRANS_CTX(Monoid w, RWST r w s)