Created
July 13, 2011 16:02
-
-
Save xfire/1080612 to your computer and use it in GitHub Desktop.
monad transformer stack example
This file contains 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.Reader | |
import Control.Monad.State | |
import Control.Monad.Writer | |
-- our monad transformer stack | |
-- a reader with an prefix string for the log | |
-- a state with the current value as integer | |
-- a writer to log the work done | |
-- all in a IO monad | |
type Prefix = String | |
type Counter = Int | |
type Log = [String] | |
type MT = ReaderT Prefix (StateT Counter (WriterT Log IO)) | |
-- get value from state | |
getS = lift $ get | |
-- modify state | |
modS f = lift $ modify f | |
-- write string to log | |
tellW s = lift $ lift $ tell [s] | |
-- count the number in the state down to 0 and | |
-- protocols every step in the writer. in doing | |
-- so, the prefix from the reader is prepended to | |
-- the logging string. | |
countDown :: MT () | |
countDown = do n <- getS | |
modS (\x -> x - 1) | |
n' <- getS | |
prefix <- ask | |
let l = prefix ++ ": count from [" ++ show n ++ "] to: [" ++ show n' ++ "]" | |
tellW l | |
liftIO $ putStrLn l | |
if n' > 0 | |
then countDown | |
else return () | |
-- initialize our monad transformer stack with a prefix value and a value | |
-- from which we can count down and run a computation k inside this context. | |
runMT :: MT a -> Prefix -> Int -> IO (a, Counter, Log) | |
runMT k prefix start = do ((a, c), l) <- runWriterT (runStateT (runReaderT k prefix) start) | |
return (a, c, l) | |
main = do | |
putStrLn "start count down..." | |
(_, c, l) <- runMT countDown "countDown" 10 | |
putStrLn "...count down finished" | |
putStrLn "" | |
putStr "the state value: " | |
putStrLn $ show c | |
putStrLn "the writer contains:" | |
mapM_ putStrLn l |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment