module Data.Machine.Lift (execStateM, catchExcept, runReaderM) where
import Control.Monad.Trans.State.Strict
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Except
import Data.Machine.Type
execStateM :: Monad m => s -> MachineT (StateT s m) k o -> MachineT m k o
execStateM s m = MachineT $ do
(stp, s') <- runStateT (runMachineT m) s
case stp of
Stop -> return Stop
Yield o m' -> return $ Yield o (execStateM s' m')
Await f k q -> return $ Await (execStateM s' . f) k (execStateM s' q)
catchExcept :: Monad m
=> MachineT (ExceptT e m) k o
-> (e -> MachineT (ExceptT e m) k o)
-> MachineT (ExceptT e m) k o
catchExcept m c = MachineT $ do
step <- runMachineT m `catchE` \e -> runMachineT (catchExcept (c e) c)
case step of
Stop -> return Stop
Yield o m' -> return $ Yield o (catchExcept m' c)
Await f k m' -> return $ Await (flip catchExcept c . f) k (catchExcept m' c)
runReaderM :: Monad m => e -> MachineT (ReaderT e m) k o -> MachineT m k o
runReaderM e = fitM (flip runReaderT e)