[Haskell-beginners] Counting sheep with the State monad

Amy de Buitléir amy at nualeargais.ie
Sun Oct 3 00:20:53 EDT 2010


I've written a very simple piece of code in order to help me
understand Monads better:

----------
import "mtl" Control.Monad.State

countAnotherSheep :: Int -> (String, Int)
countAnotherSheep n = (show n ++ " sheep", n+1)

sheepCounter = State { runState = countAnotherSheep }
----------

So far so good. Now I can do things like:

ghci> evalState sheepCounter 1
"1 sheep"
ghci> evalState sheepCounter 2
"2 sheep"

ghci> execState sheepCounter 1
2
ghci> execState sheepCounter 2
3

ghci> evalState (sequence $ replicate 5 sheepCounter) 1
["1 sheep","2 sheep","3 sheep","4 sheep","5 sheep"]

But what I really want to do is create a main function in which I:

1. Count some sheep.
2. Do something else.
3. Count some more sheep, picking up where I left off.

I could thread the state like this:

increment (_, n) = countAnotherSheep n

main = do
  let c = countAnotherSheep 1
  putStrLn $ fst c
  let c2 = increment c
  putStrLn $ fst c2
  putStrLn "Now I'll do some other stuff"
  let c3 = increment c2
  putStrLn $ fst c3

... but shouldn't the State monad make threading the state
unnecessary? It seems like there should be a way to do this, but I
can't figure it out. Thank you in advance for any suggestions.


More information about the Beginners mailing list