module Control.Eff.State.Lazy( State (..)
, get
, put
, modify
, runState
, evalState
, execState
) where
import Data.Typeable
import Control.Eff
data State s w = State (s -> s) (s -> w)
deriving (Typeable, Functor)
put :: (Typeable e, Member (State e) r) => e -> Eff r ()
put = modify . const
get :: (Typeable e, Member (State e) r) => Eff r e
get = send . inj $ State id id
modify :: (Typeable s, Member (State s) r) => (s -> s) -> Eff r ()
modify f = send . inj $ State f $ const ()
runState :: Typeable s
=> s
-> Eff (State s :> r) w
-> Eff r (s, w)
runState = loop
where
loop s = freeMap
(\x -> return (s, x))
(\u -> handleRelay u (loop s) $
\(State t k) -> let s' = t s
in loop s' (k s'))
evalState :: Typeable s => s -> Eff (State s :> r) w -> Eff r w
evalState s = fmap snd . runState s
execState :: Typeable s => s -> Eff (State s :> r) w -> Eff r s
execState s = fmap fst . runState s