# Simple StateT use

### From HaskellWiki

(Difference between revisions)

m |
|||

Line 44: | Line 44: | ||

main = do answer <- getStdRandom (randomR (1,100)) -- think of a number |
main = do answer <- getStdRandom (randomR (1,100)) -- think of a number |
||

putStrLn "I'm thinking of a number between 1 and 100, can you guess it?" |
putStrLn "I'm thinking of a number between 1 and 100, can you guess it?" |
||

− | guesses <- execStateT (guessingSession answer) 0 |
+ | guesses <- execStateT (guessSession answer) 0 |

putStrLn $ "Success in " ++ (show guesses) ++ " tries." |
putStrLn $ "Success in " ++ (show guesses) ++ " tries." |
||

Line 53: | Line 53: | ||

modify (+1) -- increment number of guesses |
modify (+1) -- increment number of guesses |
||

case compare g answer of |
case compare g answer of |
||

− | LT -> do lift $ putStrLn “Too low” |
+ | LT -> do lift $ putStrLn "Too low" |

guessSession answer |
guessSession answer |
||

− | GT -> do lift $ putStrLn “Too high” |
+ | GT -> do lift $ putStrLn "Too high" |

guessSession answer |
guessSession answer |
||

− | EQ -> lift $ putStrLn “Got it!” |
+ | EQ -> lift $ putStrLn "Got it!" |

</haskell> |
</haskell> |
||

## Revision as of 02:13, 23 April 2007

A small example showing how to combine a State monad (in this case a unique supply), with the IO monad, via a monad transformer.

No need to resort to nasty mutable variables or globals!

import Control.Monad.State main :: IO () main = runStateT code [1..] >> return () -- -- layer an infinite list of uniques over the IO monad -- code :: StateT [Integer] IO () code = do x <- pop io $ print x y <- pop io $ print y return () -- -- pop the next unique off the stack -- pop :: StateT [Integer] IO Integer pop = do (x:xs) <- get put xs return x io :: IO a -> StateT [Integer] IO a io = liftIO -- -- another example: a guessing game -- (from http://scsibug.com/2006/11/28/a-simple-game-with-statet/) -- module Main where import System.Random import Control.Monad.State main = do answer <- getStdRandom (randomR (1,100)) -- think of a number putStrLn "I'm thinking of a number between 1 and 100, can you guess it?" guesses <- execStateT (guessSession answer) 0 putStrLn $ "Success in " ++ (show guesses) ++ " tries." guessSession :: Int -> StateT Int IO () guessSession answer = do gs <- lift getLine -- get guess from user let g = read gs -- convert to number modify (+1) -- increment number of guesses case compare g answer of LT -> do lift $ putStrLn "Too low" guessSession answer GT -> do lift $ putStrLn "Too high" guessSession answer EQ -> lift $ putStrLn "Got it!"