The following describes Control.Monad.State from the hierarchical libraries (and specifically, from GHC).

## Control.Monad.State

### Description

The state monad hides state from us (if it needs to be passed as an extra parameter). This is useful when you have a few variables that need to be "updated." Common uses for State monads are unique name supplies and counters. If you just don't want to have to pass around a variable, but don't really intend to change it (or the changes are temporary) then MonadReader would likely be a better choice. MonadState is not used for references or updateable arrays; instead use the ST Monad or the IO Monad.

There is also a transformer version, StateT.

### Details

(see the hierarchical libs documentation below in References)

### Possible Implementation

*Note: this implementation requires ?MultiParameterTypeClasses and FunDeps which are *not* Haskell98*

newtype State s a = State { runState:: (s -> (a,s)) }instanceMonad (State s)wherereturn a = State $ \s -> (a,s) x >>= f = State $ \s ->let(v,s') = runState x sinrunState (f v) s'classMonadState m s | m -> swhereget:: m sput:: s -> m ()instanceMonadState (State s) swhereget = State $ \s -> (s,s) put s = State $ \_-> ((),s) gets:: (MonadState m s) => (s -> a) -> m agets f = f `liftM` get modify:: (MonadState m s) => (s -> s) -> m ()modify f = get >>= put . f

### Examples

if we were to transform a tree so that each of the leaves were numbered

we could either writedataTree a = Leaf a | Branch (Tree a) (Tree a)

numberor we could encapsulate the whole shebang in a state monad:: Int -> Tree a -> (Tree (a,Int) , Int)number seed (Leaf a) = (Leaf (a,seed),seed + 1) number seed (Branch left right) =let(left',lseed) = number seed left (right',rseed) = number lseed rightin(Branch left' right' rseed)

numberST-- ChrisAngus:: Tree a -> State Int (Tree (a,Int))numberST (Leaf a) = do next <- get put (next + 1) return Leaf (a,next) numberST (Branch l r) = do left <- numberST l right <- numberST r return (Branch left right)

A function to increment a counter. Taken from the paper *Generalising Monads to Arrows*, John Hughes (http://www.math.chalmers.se/~rjmh/), November 1998.

tickAdd one to the given number using the state monad.:: State Int Inttick = do n <- get put (n+1) return n

plusOneA contrived addition example. Works only with positive numbers.:: Int -> IntplusOne n = execState tick n

plus:: Int -> Int -> Intplus n x = execState (sequence $ replicate n tick) x

An example from *The Craft of Functional Programming*, Simon Thompson (http://www.cs.ukc.ac.uk/people/staff/sjt/), Addison-Wesley 1999: \"Given an arbitrary tree, transform it to a tree of integers in which the original elements are replaced by natural numbers, starting from 0. The same element has to be replaced by the same number at every occurrence, and when we meet an as-yet-unvisited element we have to find a 'new' number to match it with."

dataTree a = Nil | Node a (Tree a) (Tree a)deriving(Show, Eq)typeTable a = [a] testTree = Node"Zero"(Node"One"(Node"Two"Nil Nil) (Node"One"(Node"Zero"Nil Nil) Nil)) Nil numTree:: (Eq a) => Tree a -> Tree IntnumTree t = evalState (numberTree t) [] numberTree:: Eq a => Tree a -> State (Table a) (Tree Int)numberTree Nil = return Nil numberTree (Node x t1 t2) = do num <- numberNode x nt1 <- numberTree t1 nt2 <- numberTree t2 return (Node num nt1 nt2)wherenumberNode:: Eq a => a -> State (Table a) IntnumberNode x = do table <- get (newTable, newPos) <- return (nNode x table) put newTable return newPos nNode:: (Eq a) => a -> Table a -> (Table a, Int)nNode x table =case(elemIndex x table)ofNothing -> (table ++ [x], length table) Just i -> (table, i)

So for example:

numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil

There is also a construct in Control.Monad.State for encapsulating one monad inside a State monad; it's called StateT. In this example by MarkCarroll, the IO state is nested inside a state monad that carries information about our computation:

moduleNestedMonadwhereimportControl.Monad.StateimportData.List get_length:: String -> IO Intget_length name = do contents <- readFile name return (length (lines contents)) update_best_with:: MonadState (String, Int) m => (String, Int) -> m ()update_best_with (current_name, current_count) = do (best_name, best_count) <- getifcurrent_count > best_countthenput (current_name, current_count)elsereturn () do_next:: String -> StateT (String, Int) IO ()do_next name = do count <- lift $ get_length name update_best_with (name, count) longest_file:: [String] -> IO (String, Int)longest_file names = execStateT (sequence_ (map do_next names)) ("none", 0) main = do (name, count) <- longest_file ["/etc/hostname","/etc/ntp.conf","/etc/timezone"] putStrLn ("Longest file is "++ name ++" which is "++ show count ++" lines long")

### References

The base libraries for GHC provide such a construct, see the documentation for Control.Monad.State.

### Notes

*Note*: Perhaps this can be added to the StateT documentation? Does anyone have a better example? Is there a better way to describe the standardness of the Control.Monad.State module?

-- IsaacJones

### Using ReaderT in place of StateT IO

One way to simulate global variables is by using StateT on top of IO, and place the runStateT in "main" to carry the variables in a record. This approach can be made even nicer by adding a few types and accessors for external module, like this:

importControl.Monad.StatedataVars = Vars { var1:: Int,var2:: Float}typeMyState a = StateT Vars IO atypeSelector a = (MyState a, a -> MyState ()) s1:: Selector Ints1 = (gets var1, \x -> modify (\vs -> vs {var1 = x}) s2:: Selector Floats2 = (gets var2, \x -> modify (\vs -> vs {var2 = x}) sel:: Selector a -> MyState asel = fst mods:: Selector a -> (a -> a) -> MyState ()mods (gf,uf) mfun = do st <- gf uf (mfun st) sample:: MyState ()sample = do a <- sel s1 mods s2 (\x -> x * (fromIntegral a)) b <- sel s2 liftIO $ print b main = runStateT sample (Vars 2 1.3)

However, it is often easier (and faster) to replace this with a ReaderT with IORef in the record fields:

importControl.Monad.ReaderimportData.IORefdataVars = Vars { var1:: IORef Int,var2:: IORef Float}typeMyState a = ReaderT Vars IO atypeSelector a = Vars -> IORef a sel:: Selector a -> MyState asel s = do hs <- ask liftIO $ readIORef (s hs) mods:: Selector a -> (a -> a) -> MyState ()mods sel mod = do hs <- ask liftIO $ modifyIORef (sel hs) mod sample:: MyState ()sample = do a <- sel var1 mods var2 (\x -> x * (fromIntegral a)) b <- sel var2 liftIO $ print b main = do r1 <- newIORef 2 r2 <- newIORef 1.3 runReaderT sample (Vars r1 r2)