1 -----------------------------------------------------------------------------
3 -- Module : Control.Monad.State
4 -- Copyright : (c) Andy Gill 2001,
5 -- (c) Oregon Graduate Institute of Science and Technology, 2001
6 -- License : BSD-style (see the file libraries/base/LICENSE)
8 -- Maintainer : libraries@haskell.org
9 -- Stability : experimental
10 -- Portability : non-portable (multi-param classes, functional dependencies)
14 -- This module is inspired by the paper
15 -- /Functional Programming with Overloading and
16 -- Higher-Order Polymorphism/,
17 -- Mark P Jones (<http://www.cse.ogi.edu/~mpj/>)
18 -- Advanced School of Functional Programming, 1995.
20 -- See below for examples.
22 -----------------------------------------------------------------------------
24 module Control.Monad.X.StateT (
36 import Prelude (Functor(..),Monad(..),(.),fst)
39 import Control.Monad.X.Trans as T
40 import Control.Monad.X.Utils
41 import Control.Monad.X.Types(StateT(..))
43 instance MonadTrans (StateT s) where
44 lift m = S (\s -> liftM (\a -> (a,s)) m)
46 instance HasBaseMonad m n => HasBaseMonad (StateT s m) n where
49 instance (Monad m) => Functor (StateT s m) where
52 instance (Monad m) => Monad (StateT s m) where
54 m >>= k = S (\s -> do (a, s') <- m $$ s
59 runState :: Monad m => s -> StateT s m a -> m a
60 runState s m = liftM fst (runStateS s m)
62 runStateS :: s -> StateT s m a -> m (a,s)
63 runStateS s m = m $$ s
66 runStateT :: StateT s m a -> s -> m (a,s)
69 evalStateT :: (Monad m) => StateT s m a -> s -> m a
74 execStateT :: (Monad m) => StateT s m a -> s -> m s
79 mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
80 mapStateT f m = S (f . (m $$))
82 withStateT :: (s -> s) -> StateT s m a -> StateT s m a
83 withStateT f m = S ((m $$) . f)
88 instance (MonadReader r m) => MonadReader r (StateT s m) where
90 local = local' mapStateT
92 instance (MonadWriter w m) => MonadWriter w (StateT s m) where
94 listen = listen2' S unS (\w (a,s) -> ((a,w),s))
96 instance (Monad m) => MonadState s (StateT s m) where
97 get = S (\s -> return (s, s))
98 put s = S (\_ -> return ((), s))
100 instance (MonadError e m) => MonadError e (StateT s m) where
101 throwError = throwError'
102 catchError = catchError2' S ($$)
104 instance (MonadPlus m) => MonadPlus (StateT s m) where
106 mplus = mplus2' S ($$)
108 -- 'findAll' does not affect the state
109 -- if interested in the state as well as the result, use
110 -- `get` before `findAll`.
111 -- e.g. findAllSt m = findAll (do x <- m; y <- get; reutrn (x,y))
112 instance MonadNondet m => MonadNondet (StateT s m) where
113 findAll m = S (\s -> liftM (\xs -> (fmap fst xs,s)) (findAll (m $$ s)))
114 commit = mapStateT commit
116 instance MonadResume m => MonadResume (StateT s m) where
117 delay = mapStateT delay
118 force = mapStateT force
120 -- jumping undoes changes to the state state
121 instance MonadCont m => MonadCont (StateT s m) where
122 callCC = callCC2' S unS (\a s -> (a,s))