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(..))
import Data.Monoid ( Monoid )
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)
#if MIN_VERSION_transformers(0,4,0)
import Control.Monad.Trans.Except (ExceptT)
#endif
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)
#if MIN_VERSION_transformers(0,4,0)
LIFTP(ExceptT e)
#endif
#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)
#if MIN_VERSION_transformers(0,4,0)
TRANS(ExceptT e)
#endif
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)