Created
June 9, 2019 15:41
-
-
Save joshcough/5e649e08c794bbce3442f13d4bcd492b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad.RWS.Lazy | |
data Action = Fail | Proceed | |
data Command = Command1 | Command2 | |
newtype MyState = MyState Int | |
-- step function that might do some IO while processing Commands | |
-- such as going to the database before producing an Action and the next State | |
stepM :: Monad m => MyState -> Command -> m (Action, Maybe MyState) | |
stepM = undefined | |
-- single step in the interpreter, manages state propagation | |
stepRWST :: Monad m => Command -> RWST () [Action] (Maybe MyState) m (Maybe MyState) | |
stepRWST c = RWST $ \_ ms -> case ms of | |
Nothing -> return (Nothing, Nothing, []) | |
Just s -> do | |
(a, ms') <- stepM s c | |
return (ms', ms', [a]) | |
-- generic driver of computation | |
interpretM' :: Monad m => [c] -> s -> (c -> RWST () [w] s m a) -> m ([a], s, [w]) | |
interpretM' commands initState f = runRWST (traverse f commands) () initState | |
-- the actual interpreter | |
interpretM :: Monad m => [Command] -> MyState -> m [(Action, Maybe MyState)] | |
interpretM commands initState = do | |
(as, _, ws) <- interpretM' commands (Just initState) stepRWST | |
return $ zip ws as | |
-- an example of using the interpreter | |
testM :: Monad m => m [(Action, Maybe MyState)] | |
testM = interpretM [Command1, Command2] (MyState 42) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment