1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
-----------------------------------------------------------------------------
-- |
-- Module : Control.Monad.State.Class
-- Copyright : (c) Andy Gill 2001,
-- (c) Oregon Graduate Institute of Science and Technology, 2001
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : ross@soi.city.ac.uk
-- Stability : experimental
-- Portability : non-portable (type families)
--
-- MonadState class.
--
-- This module is inspired by the paper
-- /Functional Programming with Overloading and
-- Higher-Order Polymorphism/,
-- Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
-- Advanced School of Functional Programming, 1995.
-----------------------------------------------------------------------------
module Control.Monad.State.Class (
MonadState(..),
modify,
gets,
) where
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Cont
import Control.Monad.Trans.Error
import Control.Monad.Trans.Identity
import Control.Monad.Trans.List
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Reader
import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, get, put)
import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, get, put)
import qualified Control.Monad.Trans.State.Lazy as Lazy (StateT, get, put)
import qualified Control.Monad.Trans.State.Strict as Strict (StateT, get, put)
import Control.Monad.Trans.Writer.Lazy as Lazy
import Control.Monad.Trans.Writer.Strict as Strict
import Control.Monad
import Data.Monoid
-- ---------------------------------------------------------------------------
-- | /get/ returns the state from the internals of the monad.
--
-- /put/ replaces the state inside the monad.
class (Monad m) => MonadState m where
type StateType m
get :: m (StateType m)
put :: StateType m -> m ()
-- | Monadic state transformer.
--
-- Maps an old state to a new state inside a state monad.
-- The old state is thrown away.
--
-- > Main> :t modify ((+1) :: Int -> Int)
-- > modify (...) :: (MonadState Int a) => a ()
--
-- This says that @modify (+1)@ acts over any
-- Monad that is a member of the @MonadState@ class,
-- with an @Int@ state.
modify :: (MonadState m) => (StateType m -> StateType m) -> m ()
modify f = do
s <- get
put (f s)
-- | Gets specific component of the state, using a projection function
-- supplied.
gets :: (MonadState m) => (StateType m -> a) -> m a
gets f = do
s <- get
return (f s)
instance (Monad m) => MonadState (Lazy.StateT s m) where
type StateType (Lazy.StateT s m) = s
get = Lazy.get
put = Lazy.put
instance (Monad m) => MonadState (Strict.StateT s m) where
type StateType (Strict.StateT s m) = s
get = Strict.get
put = Strict.put
instance (Monad m, Monoid w) => MonadState (LazyRWS.RWST r w s m) where
type StateType (LazyRWS.RWST r w s m) = s
get = LazyRWS.get
put = LazyRWS.put
instance (Monad m, Monoid w) => MonadState (StrictRWS.RWST r w s m) where
type StateType (StrictRWS.RWST r w s m) = s
get = StrictRWS.get
put = StrictRWS.put
-- ---------------------------------------------------------------------------
-- Instances for other mtl transformers
instance (MonadState m) => MonadState (ContT r m) where
type StateType (ContT r m) = StateType m
get = lift get
put = lift . put
instance (Error e, MonadState m) => MonadState (ErrorT e m) where
type StateType (ErrorT e m) = StateType m
get = lift get
put = lift . put
instance (MonadState m) => MonadState (IdentityT m) where
type StateType (IdentityT m) = StateType m
get = lift get
put = lift . put
instance (MonadState m) => MonadState (ListT m) where
type StateType (ListT m) = StateType m
get = lift get
put = lift . put
instance (MonadState m) => MonadState (MaybeT m) where
type StateType (MaybeT m) = StateType m
get = lift get
put = lift . put
instance (MonadState m) => MonadState (ReaderT r m) where
type StateType (ReaderT r m) = StateType m
get = lift get
put = lift . put
instance (Monoid w, MonadState m) => MonadState (Lazy.WriterT w m) where
type StateType (Lazy.WriterT w m) = StateType m
get = lift get
put = lift . put
instance (Monoid w, MonadState m) => MonadState (Strict.WriterT w m) where
type StateType (Strict.WriterT w m) = StateType m
get = lift get
put = lift . put
|