th-typegraph-0.24: Language/Haskell/TH/TypeGraph/HasState.hs
-- | MonadState without the function dependency @m -> s@.
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Language.Haskell.TH.TypeGraph.HasState
( HasState(getState, modifyState)
) where
import Control.Monad.Reader (ReaderT)
import Control.Monad.RWS (RWST)
import Control.Monad.State (StateT, get, modify)
import Control.Monad.Trans (lift)
import Control.Monad.Writer (WriterT)
-- | This class allows you to access bits of the State by type,
-- without knowing exactly what the overall state type is. For
-- example:
--
-- typeGraphEdges :: (DsMonad m,
-- MonadReader TypeGraph m,
-- HasState (Set TGV) m,
-- HasState (Map Type (E Type)) m) => ...
--
-- This will work as long as the two HasState instances exist for
-- whatever the actual State type is. It still can't reach down
-- into nested StateT monads, you may need to use lift for that.
class HasState s m where
getState :: m s
modifyState :: (s -> s) -> m ()
instance Monad m => HasState s (StateT s m) where
getState = get
modifyState = modify
instance (Monad m, Monoid w) => HasState s (RWST r w s m) where
getState = get
modifyState = modify
instance (Monad m, HasState s m) => HasState s (ReaderT r m) where
getState = lift getState
modifyState f = lift $ modifyState f
instance (Monad m, Monoid w, HasState s m) => HasState s (WriterT w m) where
getState = lift getState
modifyState f = lift $ modifyState f