State
monadicon.icon
Overview
We pass state to a function as an argument.
The function modifies the state and produces it as a result.
If the function does anything except modifying the state, we must return a tuple (or a special-purpose datatype with multiple fields).
code:state.hs
type State s a = s -> (a, s)
State can be used to
maintain random number generator
maintain counter to generate unique labels
maintaining the complete current configuration of an application (an interpreter, a game, ...) using a user-defined datatype
code:state.hs
type Random a = State StdGen a
type Counter a = State Int a
-- Given there's user-defined datatype
data ProgramState = ...
type Program a = State ProgramState a
code:helper.hs
get :: State s s
get = \s -> (s,s)
put :: s -> State s ()
puts = \ _ -> ((),s)
evalState :: States a -> s -> a -- takes initial state and run computation
runState :: State s a -> s -> (a, s) -- unpacking State ’s newtype wrapper
Label binary tree
code:binarytree.hs
data Tree a = Leaf a | Node (Tree a) (Tree a)
labelTree :: Tree a -> State Int (Tree (a, Int))
labelTree (Leaf x) = do
c <- get
put (c + 1) -- or modify(+1) return (Leaf (x, c))
labelTree (Node l r) = do
ll <- labelTree l
lr <- labelTree r
return (Node ll lr)
Useful link