Personal tools

Simple StateT use

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
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!"