Skip to content

Instantly share code, notes, and snippets.

@stesh
Created April 25, 2013 01:31
Show Gist options
  • Select an option

  • Save stesh/5456884 to your computer and use it in GitHub Desktop.

Select an option

Save stesh/5456884 to your computer and use it in GitHub Desktop.
The State transformer monad
-- State transformer monad --
--
-- 1. Typeclass MonadState, declaring stateful operations
-- 2. A datatype to work with
-- 3. An implementation of Monad
-- 4. An implementation of MonadTrans
-- 5. An implementation of MonadState
-- 6. The State Monad for free, by transforming Identity
class (Monad m) => MonadState s m | m -> s where
-- get the current state out of the monad
get :: m s
-- insert a new state into the monad
put :: s -> m ()
newtype StateT s m a = StateT {
-- s: the initial state
-- m: the inner monad
-- Make rocket go now.
runStateT :: s -> m (a, s)
}
instance (Monad m) => Monad (StateT s m) where
-- RHS `return` is the inner monad's return
return a = StateT $ \s -> return (a, s)
m >>= k = StateT $ \s -> do
-- Obtain the new value and state from m, given current state s
(a, s') <- runStateT m s
-- k $ a does the binding
-- thread the new state s' into the continuation
runStateT (k a) s'
instance (Monad m) => MonadTrans (StateT s m) where
-- to lift an inner monadic action into this monad,
-- perform it in the inner monad, and leave the state
-- untouched.
lift m = StateT $ \s -> do
a <- m
return (a, s)
instance (Monad m) => MonadState (StateT s m) where
-- return a StateT step which happens to have the current state as its
-- value, and which doesn't modify the current state in the process
get = StateT $ \s -> return (s, s)
-- return a StateT step which, no matter what the current state is,
-- overwrites it with the given state.
put s = StateT $ \_ -> return ((), s)
newtype Identity a = Identity {
runIdentity :: a
}
instance Monad Identity where
return a = Identity a
m >>= k = k $ runIdentity m
type State s = StateT s Identity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment