module Data.Monoid.State where import qualified Data.Monoid.Transformer as MonoidTrans import Data.Monoid (Monoid, mempty, mappend, ) newtype T s a = Cons {run :: s -> (a,s)} evaluate :: s -> T s a -> a evaluate s m = fst $ run m s execute :: s -> T s a -> s execute s m = snd $ run m s put :: Monoid a => s -> T s a put s = Cons $ const (mempty, s) modify :: Monoid a => (s -> s) -> T s a modify f = Cons $ \s -> (mempty, f s) instance Monoid a => Monoid (T s a) where mempty = MonoidTrans.lift mempty mappend (Cons x) (Cons y) = Cons $ \s0 -> let (xr,s1) = x s0 (yr,s2) = y s1 in (mappend xr yr, s2) instance MonoidTrans.C (T r) where lift x = Cons $ (,) x