-- This module provides the familiar state effect. module Control.Effects.State where import Control.Effects.Eff import Control.Monad -- |The functor representing the effect. You shouldn't need -- to create this manually, just use `get`, `put` or `state`. data State s a = SGet (s -> a) | SPut s a deriving (Functor, Typeable) -- |Read from state get :: (Member (State a) r, Typeable a) => Eff r a get = effect $ \k -> inj $ SGet k -- |Write to state put :: (Member (State s) r, Typeable s) => s -> Eff r () put a = effect $ \k -> inj $ SPut a $ k () -- |Lift a function into state state :: (Member (State s) r, Typeable s) => (s -> (a, s)) -> Eff r a state f = do s <- get let (a, s') = f s put s' return a -- |Handle state into a function. Note that applying the resulting -- function you get out another program that you have to bind over. stateHandler :: Handler (State s) r a (s -> Eff r a) stateHandler (Value a) = return $ const $ return a stateHandler (Comp (SGet k)) = return $ \s -> join $ ($s) `fmap` continue (k s) stateHandler (Comp (SPut s k)) = return $ \_ -> join $ continue $ fmap ($s) k