module Control.Monad.Trans.Interruptible.Class (
Interruptible(..),
inEitherTCtx, peelEitherTCtx,
inStateTCtx, peelStateTCtx,
inWriterTCtx, peelWriterTCtx,
inReaderTCtx, peelReaderTCtx,
inRWSTCtx, peelRWSTCtx,
resume2,
resume3,
resume4,
resume5
)where
import Control.Monad.Trans.Class
import Control.Monad.Trans.State
import Control.Monad.Trans.Either
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Writer
import Control.Monad.Trans.RWS
class MonadTrans t => Interruptible t where
type RSt t a :: *
resume :: Monad m => (a -> t m b) -> RSt t a -> m (RSt t b)
instance Interruptible (EitherT e) where
type RSt (EitherT e) a = Either e a
resume f st = runEitherT (hoistEither st >>= f)
inEitherTCtx :: a -> RSt (EitherT e) a
inEitherTCtx = Right
peelEitherTCtx :: RSt (EitherT e) a -> Either e a
peelEitherTCtx = id
instance Interruptible (StateT st) where
type RSt (StateT st) a = (a, st)
resume f (a, st) = runStateT (f a) st
inStateTCtx :: st -> a -> RSt (StateT st) a
inStateTCtx st a = (a, st)
peelStateTCtx :: RSt (StateT st) a -> (a, st)
peelStateTCtx = id
instance Monoid w => Interruptible (WriterT w) where
type RSt (WriterT w) a = (a, w)
resume f (a, w) = do
(a', w') <- runWriterT (f a)
return (a', mappend w w')
inWriterTCtx :: Monoid w => a -> RSt (WriterT w) a
inWriterTCtx a = (a, mempty)
peelWriterTCtx :: RSt (WriterT w) a -> (a, w)
peelWriterTCtx = id
instance Interruptible (ReaderT r) where
type RSt (ReaderT r) a = (a, r)
resume f (a, r) = do
a' <- runReaderT (f a) r
return (a', r)
inReaderTCtx :: r -> a -> RSt (ReaderT r) a
inReaderTCtx r a = (a, r)
peelReaderTCtx :: RSt (ReaderT r) a -> a
peelReaderTCtx (a, _) = a
instance Monoid w => Interruptible (RWST r w s) where
type RSt (RWST r w s) a = (a, r, w, s)
resume f (a, r, w, s) = do
(a', s', w') <- runRWST (f a) r s
return (a', r, w', s')
inRWSTCtx :: Monoid w => r -> s -> a -> RSt (RWST r w s) a
inRWSTCtx r s a = (a, r, mempty, s)
peelRWSTCtx :: RSt (RWST r w s) a -> (a, w, s)
peelRWSTCtx (a, r, w, s) = (a, w, s)
resume2 :: (Monad m, Interruptible t, Monad (t m), Interruptible u) =>
(a -> u (t m) b) -> RSt t (RSt u a) -> m (RSt t (RSt u b))
resume2 = resume.resume
resume3 :: (Monad m, Interruptible t0, Monad (t0 m), Interruptible t1,
Monad (t1 (t0 m)), Interruptible t2) =>
(a -> t2 (t1 (t0 m)) b) -> RSt t0 (RSt t1 (RSt t2 a)) ->
m (RSt t0 (RSt t1 (RSt t2 b)))
resume3 = resume2.resume
resume4 :: (Monad m, Interruptible t0, Interruptible t1, Interruptible t2,
Interruptible t3, Monad (t0 m), Monad (t1 (t0 m)), Monad (t2 (t1 (t0 m)))) =>
(a -> t3 (t2 (t1 (t0 m))) b) -> RSt t0 (RSt t1 (RSt t2 (RSt t3 a))) ->
m (RSt t0 (RSt t1 (RSt t2 (RSt t3 b))))
resume4 = resume3.resume
resume5 :: (Monad m, Interruptible t0, Interruptible t1, Interruptible t2,
Interruptible t3, Interruptible t4, Monad (t0 m), Monad (t1 (t0 m)),
Monad (t2 (t1 (t0 m))), Monad (t3 (t2 (t1 (t0 m))))) =>
(a -> t4 (t3 (t2 (t1 (t0 m)))) b) -> RSt t0 (RSt t1 (RSt t2 (RSt t3 (RSt t4 a)))) ->
m (RSt t0 (RSt t1 (RSt t2 (RSt t3 (RSt t4 b)))))
resume5 = resume4.resume