Skip to content

Instantly share code, notes, and snippets.

@tranma
Created October 14, 2014 01:42
Show Gist options
  • Save tranma/9d4a335a0dfe90f1cfbb to your computer and use it in GitHub Desktop.
Save tranma/9d4a335a0dfe90f1cfbb to your computer and use it in GitHub Desktop.
squash StateTs that have the same monoid as state
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Applicative
import Control.Monad.Trans.State.Strict
import Control.Monad.Trans.Class
import Control.Monad.Morph
import Data.Monoid
newtype MonoidState m a = MonoidState { st :: StateT [Int] m a }
deriving (Functor, Applicative, Monad, MonadTrans, MFunctor)
instance MMonad MonoidState where
embed f m = MonoidState $ StateT (\s -> do
((a, s1), s2) <- runStateT (st $ f (runStateT (st m) s)) s
return (a, mappend s2 s1))
foo :: Monad m => MonoidState (MonoidState m) ()
foo = MonoidState $ do put [0,4,7]
lift $ MonoidState $ do x <- get
put (9:1:x)
main = do
s <- execStateT (st $ squash foo) []
putStrLn (show s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment