@@ -7,16 +7,20 @@
77{-# LANGUAGE TypeOperators #-}
88{-# LANGUAGE GeneralizedNewtypeDeriving #-}
99module Control.Monad.Trans.Ether.State
10− ( StateT
11− , State
12− , runStateT
10+ (
11+ -- * The State monad
12+ State
1313 , runState
14− , evalStateT
1514 , evalState
16− , execStateT
1715 , execState
16+ -- * The StateT monad transformer
17+ , StateT
1818 , stateT
19+ , runStateT
20+ , evalStateT
21+ , execStateT
1922 , mapStateT
23+ -- * Litfing other operations
2024 , liftCatch
2125 , liftCallCC'
2226 , liftListen
@@ -42,47 +46,82 @@ import qualified Control.Monad.State.Class as Class
4246import qualified Control.Monad.Writer.Class as Class
4347import qualified Control.Monad.Error.Class as Class
4448
49+
50+-- | The parametrizable state monad.
51+--
52+-- Computations have access to a mutable state.
53+--
54+-- The 'return' function leaves the state unchanged, while '>>=' uses
55+-- the final state of the first computation as the initial state of
56+-- the second.
57+type State tag r = StateT tag r Identity
58+
59+-- | The state monad transformer.
60+--
61+-- The 'return' function leaves the state unchanged, while '>>=' uses
62+-- the final state of the first computation as the initial state of
63+-- the second.
4564newtype StateT tag s m a = StateT (Trans.StateT s m a)
4665 deriving ( Functor, Applicative, Alternative, Monad, MonadPlus
4766 , MonadFix, MonadTrans, MonadIO )
4867
4968type instance Tags (StateT tag r m) = tag ': Tags m
5069
51−type State tag r = StateT tag r Identity
52−
70+-- | Constructor for computations in the state monad transformer.
5371stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
5472stateT _proxy = StateT . Trans.StateT
5573
74+-- | Runs a 'StateT' with the given initial state
75+-- and returns both the final value and the final state.
5676runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
5777runStateT _proxy (StateT (Trans.StateT f)) = f
5878
59−runState :: proxy tag -> State tag s a -> s -> (a, s)
60−runState proxy m s = runIdentity (runStateT proxy m s)
61−
79+-- | Runs a 'StateT' with the given initial state
80+-- and returns the final value, discarding the final state.
6281evalStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m a
6382evalStateT proxy m s = fmap fst (runStateT proxy m s)
6483
65−evalState :: proxy tag -> State tag s a -> s -> a
66−evalState proxy m s = fst (runState proxy m s)
67−
84+-- | Runs a 'StateT' with the given initial state
85+-- and returns the final state, discarding the final value.
6886execStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m s
6987execStateT proxy m s = fmap snd (runStateT proxy m s)
7088
89+-- | Runs a 'State' with the given initial state
90+-- and returns both the final value and the final state.
91+runState :: proxy tag -> State tag s a -> s -> (a, s)
92+runState proxy m s = runIdentity (runStateT proxy m s)
93+
94+-- | Runs a 'State' with the given initial state
95+-- and returns the final value, discarding the final state.
96+evalState :: proxy tag -> State tag s a -> s -> a
97+evalState proxy m s = runIdentity (evalStateT proxy m s)
98+
99+-- | Runs a 'State' with the given initial state
100+-- and returns the final state, discarding the final value.
71101execState :: proxy tag -> State tag s a -> s -> s
72−execState proxy m s = snd (runState proxy m s)
102+execState proxy m s = runIdentity (execStateT proxy m s)
73103
104+-- | Transform the computation inside a 'StateT'.
105+--
106+-- * @'runStateT' tag ('mapStateT' tag f m) = f . 'runStateT' tag m@
74107mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
75108mapStateT _proxy f m = StateT $ Trans.mapStateT f (coerce m)
76109
110+-- | Lift a @catchE@ operation to the new monad.
77111liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
78112liftCatch _proxy f m h = StateT $ Trans.liftCatch f (coerce m) (coerce h)
79113
80−liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
81−liftCallCC' _proxy callCC f = StateT $ Trans.liftCallCC' callCC (coerce f)
82−
114+-- | Lift a @listen@ operation to the new monad.
83115liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
84116liftListen _proxy listen m = StateT $ Trans.liftListen listen (coerce m)
85117
118+-- | In-situ lifting of a @callCC@ operation to the new monad.
119+-- This version uses the current state on entering the continuation.
120+-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
121+liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
122+liftCallCC' _proxy callCC f = StateT $ Trans.liftCallCC' callCC (coerce f)
123+
124+-- | Lift a @pass@ operation to the new monad.
86125liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
87126liftPass _proxy pass m = StateT $ Trans.liftPass pass (coerce m)
88127