------------------------------------------------------------------------------
--- This library provides an implementation of the state monad.
---
--- @author Jan-Hendrik Matthes, Bjoern Peemoeller, Fabian Skrlac
--- @version August 2016
--- @category general
------------------------------------------------------------------------------
module State
( State
, bindS, bindS_, returnS, getS, putS, modifyS, sequenceS, sequenceS_, mapS
, mapS_, runState, evalState, execState, liftS, liftS2
) where
infixl 1 `bindS`, `bindS_`
type State s a = s -> (a, s)
bindS :: State s a -> (a -> State s b) -> State s b
bindS state f s = case state s of
(x, newS) -> newS `seq` (f x newS)
bindS_ :: State s a -> State s b -> State s b
bindS_ a b = a `bindS` (\_ -> b)
returnS :: a -> State s a
returnS x s = (x, s)
getS :: State s s
getS s = (s, s)
putS :: s -> State s ()
putS newS _ = ((), newS)
modifyS :: (s -> s) -> State s ()
modifyS f s = ((), f s)
sequenceS :: [State s a] -> State s [a]
sequenceS = foldr (\s newS -> s `bindS`
(\a -> newS `bindS` (\as -> returnS (a:as))))
(returnS [])
sequenceS_ :: [State s a] -> State s ()
sequenceS_ = foldr bindS_ (returnS ())
mapS :: (a -> State s b) -> [a] -> State s [b]
mapS f = sequenceS . (map f)
mapS_ :: (a -> State s b) -> [a] -> State s ()
mapS_ f = sequenceS_ . (map f)
runState :: State s a -> s -> (a, s)
runState state s = state s
evalState :: State s a -> s -> a
evalState state s = fst (runState state s)
execState :: State s a -> s -> s
execState state s = snd (runState state s)
liftS :: (a -> b) -> State s a -> State s b
liftS f act = act `bindS` (returnS . f)
liftS2 :: (a -> b -> c) -> State s a -> State s b -> State s c
liftS2 f a b = a `bindS` (\x -> b `bindS` (\y -> returnS (f x y)))