module Control.Monad.Trans.Ether.State.Strict
(
State
, state
, runState
, evalState
, execState
, StateT
, stateT
, runStateT
, evalStateT
, execStateT
, mapStateT
, get
, put
, liftCatch
, liftCallCC'
, liftListen
, liftPass
) where
import Data.Proxy (Proxy(Proxy))
import Data.Functor.Identity (Identity(..))
import Data.Coerce (coerce)
import Control.Applicative
import Control.Monad (MonadPlus)
import Control.Monad.Fix (MonadFix)
import Control.Monad.Trans.Class (MonadTrans, lift)
import Control.Monad.IO.Class (MonadIO)
import Control.Ether.Tagged (Taggable(..), Tagged(..))
import GHC.Generics (Generic)
import qualified Control.Newtype as NT
import qualified Control.Monad.Signatures as Sig
import qualified Control.Monad.Trans.State.Strict as Trans
import qualified Control.Monad.Cont.Class as Class
import qualified Control.Monad.Reader.Class as Class
import qualified Control.Monad.State.Class as Class
import qualified Control.Monad.Writer.Class as Class
import qualified Control.Monad.Error.Class as Class
type State tag r = StateT tag r Identity
newtype StateT tag s m a = StateT (Trans.StateT s m a)
deriving ( Generic
, Functor, Applicative, Alternative, Monad, MonadPlus
, MonadFix, MonadTrans, MonadIO )
instance NT.Newtype (StateT tag s m a)
instance Taggable (StateT tag s m) where
type Tag (StateT tag s m) = 'Just tag
type Inner (StateT tag s m) = 'Just m
instance Tagged (StateT tag s m) tag where
type Untagged (StateT tag s m) = Trans.StateT s m
stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
stateT t = tagged t . Trans.StateT
state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
state t = tagged t . Trans.state
runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
runStateT t = Trans.runStateT . untagged t
evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
evalStateT t = Trans.evalStateT . untagged t
execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
execStateT t = Trans.execStateT . untagged t
runState :: proxy tag -> State tag s a -> s -> (a, s)
runState t = Trans.runState . untagged t
evalState :: proxy tag -> State tag s a -> s -> a
evalState t = Trans.evalState . untagged t
execState :: proxy tag -> State tag s a -> s -> s
execState t = Trans.execState . untagged t
mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
mapStateT t f m = tagged t $ Trans.mapStateT f (coerce m)
get :: Monad m => proxy tag -> StateT tag s m s
get t = tagged t Trans.get
put :: Monad m => proxy tag -> s -> StateT tag s m ()
put t = tagged t . Trans.put
liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
liftCatch t f m h = tagged t $ Trans.liftCatch f (coerce m) (coerce h)
liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
liftListen t listen m = tagged t $ Trans.liftListen listen (coerce m)
liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
liftCallCC' t callCC f = tagged t $ Trans.liftCallCC' callCC (coerce f)
liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
liftPass t pass m = tagged t $ Trans.liftPass pass (coerce m)
instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
callCC = liftCallCC' Proxy Class.callCC
instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
ask = lift Class.ask
local = mapStateT Proxy . Class.local
reader = lift . Class.reader
instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
get = lift Class.get
put = lift . Class.put
state = lift . Class.state
instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
writer = lift . Class.writer
tell = lift . Class.tell
listen = liftListen Proxy Class.listen
pass = liftPass Proxy Class.pass
instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
throwError = lift . Class.throwError
catchError = liftCatch Proxy Class.catchError