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)
modify :: (Typeable s, Member (State s) r) => (s -> s) -> Eff r ()
modify f = send $ \k -> inj $ State f $ \_ -> k ()
runState :: Typeable s
=> s
-> Eff (State s :> r) w
-> Eff r (s, w)
runState s0 = loop s0 . admin where
loop s (Val x) = return (s, x)
loop s (E 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