Idris2/libs/base/Control/Monad/State/Interface.idr

81 lines
2.2 KiB
Idris
Raw Normal View History

2021-01-19 13:45:54 +03:00
module Control.Monad.State.Interface
import Control.Monad.Maybe
import Control.Monad.Error.Either
import Control.Monad.Reader.Reader
import Control.Monad.State.State
import Control.Monad.RWS.CPS
import Control.Monad.Trans
import Control.Monad.Writer.CPS
%default total
||| A computation which runs in a context and produces an output
public export
interface Monad m => MonadState stateType m | m where
||| Get the context
get : m stateType
||| Write a new context/output
put : stateType -> m ()
||| Embed a simple state action into the monad.
state : (stateType -> (stateType,a)) -> m a
state f = do s <- get
let (s2,a) = f s
put s2
pure a
||| Apply a function to modify the context of this computation
public export
modify : MonadState stateType m => (stateType -> stateType) -> m ()
modify f
= do s <- get
put (f s)
||| Evaluate a function in the context held by this computation
public export
gets : MonadState stateType m => (stateType -> a) -> m a
gets f
= do s <- get
pure (f s)
--------------------------------------------------------------------------------
-- Implementations
--------------------------------------------------------------------------------
public export %inline
Monad m => MonadState stateType (StateT stateType m) where
get = ST (\x => pure (x, x))
put x = ST (\y => pure (x, ()))
state f = ST $ pure . f
public export %inline
MonadState s m => MonadState s (EitherT e m) where
get = lift get
put = lift . put
state = lift . state
public export %inline
MonadState s m => MonadState s (MaybeT m) where
get = lift get
put = lift . put
state = lift . state
public export %inline
Monad m => MonadState s (RWST r w s m) where
get = MkRWST \_,s,w => pure (s,s,w)
put s = MkRWST \_,_,w => pure ((),s,w)
state f = MkRWST \_,s,w => let (s',a) = f s in pure (a,s',w)
public export %inline
MonadState s m => MonadState s (ReaderT r m) where
get = lift get
put = lift . put
state = lift . state
public export %inline
MonadState s m => MonadState s (WriterT r m) where
get = lift get
put = lift . put
state = lift . state