on master help sign in
Update documentation
7a1d203Index Int
src/Control/Ether/TH.hs+8
@@ -17,6 +17,14 @@ proxySimple name ty = do
17 val <- funSimple name [e| Proxy |]
17 val <- funSimple name [e| Proxy |]
18 return (sig, val)
18 return (sig, val)
19
19
20+-- |
21+-- Creates a tag and a value-level proxy for it.
22+--
23+-- @'ethereal' \"Foo\" \"foo\"@ generates the following code:
24+--
25+-- > data Foo
26+-- > foo :: Proxy Foo
27+-- > foo = Proxy
20ethereal :: String -> String -> TH.DecsQ
28ethereal :: String -> String -> TH.DecsQ
21ethereal strTagName strTagProxyName = do
29ethereal strTagName strTagProxyName = do
22 let tagName = TH.mkName strTagName
30 let tagName = TH.mkName strTagName
src/Control/Ether/Tags.hs+15−1
@@ -30,7 +30,10 @@ import qualified Control.Monad.Trans.State.Strict as Trans.Strict
30import qualified Control.Monad.Trans.Writer.Lazy as Trans.Lazy
30import qualified Control.Monad.Trans.Writer.Lazy as Trans.Lazy
31import qualified Control.Monad.Trans.Writer.Strict as Trans.Strict
31import qualified Control.Monad.Trans.Writer.Strict as Trans.Strict
32
32
33−-- Never declare instances for this class
33+-- |
34+-- The main purpose of the 'UniqueTag' class is to provide clear error
35+-- messages when the tag uniqueness property is violated. You should never
36+-- provide instances for it unless you know what you're doing.
34class UniqueTag a
37class UniqueTag a
35
38
36type family IsUnique (x :: k) (as :: [k]) :: Constraint where
39type family IsUnique (x :: k) (as :: [k]) :: Constraint where
@@ -42,12 +45,23 @@ type family Unique (as :: [k]) :: Constraint where
42 Unique '[] = ()
45 Unique '[] = ()
43 Unique (a ': as) = (IsUnique a as, Unique as)
46 Unique (a ': as) = (IsUnique a as, Unique as)
44
47
48+-- |
49+-- The 'UniqueTags` constraint placed on a type variable representing a
50+-- monad transformer stack ensures that every tag in the stack appears
51+-- only once.
45type family UniqueTags (m :: * -> *) :: Constraint where
52type family UniqueTags (m :: * -> *) :: Constraint where
46 UniqueTags m = Unique (Tags m)
53 UniqueTags m = Unique (Tags m)
47
54
55+-- |
56+-- Type-restricted version of 'id' that adds a 'UniqueTags' constraint to
57+-- the provided monadic value.
48ensureUniqueTags :: UniqueTags m => m a -> m a
58ensureUniqueTags :: UniqueTags m => m a -> m a
49ensureUniqueTags = id
59ensureUniqueTags = id
50
60
61+-- |
62+-- The 'Tags' type family returns a type-level list of all tags of its argument
63+-- @m@. Simple monads have no tags, monad transformers propagate the tags of
64+-- their inner monads, and tagged monad transformers also add their own tag.
51type family Tags (m :: * -> *) :: [*]
65type family Tags (m :: * -> *) :: [*]
52
66
53type instance Tags IO = '[]
67type instance Tags IO = '[]
src/Control/Monad/Ether/Reader.hs+2
@@ -20,7 +20,9 @@ module Control.Monad.Ether.Reader
20 , runReader
20 , runReader
21 -- * The ReaderT monad transformer
21 -- * The ReaderT monad transformer
22 , ReaderT
22 , ReaderT
23+ , readerT
23 , runReaderT
24 , runReaderT
25+ , mapStateT
24 ) where
26 ) where
25
27
26import Data.Proxy (Proxy(Proxy))
28import Data.Proxy (Proxy(Proxy))
src/Control/Monad/Ether/State.hs+21−14
@@ -11,21 +11,23 @@
11{-# LANGUAGE RankNTypes #-}
11{-# LANGUAGE RankNTypes #-}
12{-# LANGUAGE GeneralizedNewtypeDeriving #-}
12{-# LANGUAGE GeneralizedNewtypeDeriving #-}
13module Control.Monad.Ether.State
13module Control.Monad.Ether.State
14− ( StateT
14+ (
15+ -- * MonadState class
16+ MonadState(..)
17+ , modify
18+ , gets
19+ -- * The State monad
15 , State
20 , State
16− , runStateT
17 , runState
21 , runState
18− , evalStateT
19 , evalState
22 , evalState
20− , execStateT
21 , execState
23 , execState
22− --
24+ -- * The StateT monad transformer
23− , MonadState
25+ , StateT
24− , get
26+ , stateT
25− , gets
27+ , runStateT
26− , put
28+ , evalStateT
27− , state
29+ , execStateT
28− , modify
30+ , mapStateT
29 ) where
31 ) where
30
32
31import Control.Monad.Trans (lift)
33import Control.Monad.Trans (lift)
@@ -49,12 +51,15 @@ class Monad m => MonadState tag s m | m tag -> s where
49
51
50 {-# MINIMAL state | get, put #-}
52 {-# MINIMAL state | get, put #-}
51
53
54+ -- | Return the state from the internals of the monad.
52 get :: proxy tag -> m s
55 get :: proxy tag -> m s
53 get proxy = state proxy (\s -> (s, s))
56 get proxy = state proxy (\s -> (s, s))
54
57
58+ -- | Replace the state inside the monad.
55 put :: proxy tag -> s -> m ()
59 put :: proxy tag -> s -> m ()
56 put proxy s = state proxy (\_ -> ((), s))
60 put proxy s = state proxy (\_ -> ((), s))
57
61
62+ -- | Embed a simple state action into the monad.
58 state :: proxy tag -> (s -> (a, s)) -> m a
63 state :: proxy tag -> (s -> (a, s)) -> m a
59 state proxy f = do
64 state proxy f = do
60 s <- get proxy
65 s <- get proxy
@@ -62,12 +67,14 @@ class Monad m => MonadState tag s m | m tag -> s where
62 put proxy s'
67 put proxy s'
63 return a
68 return a
64
69
65−gets :: MonadState tag s m => proxy tag -> (s -> a) -> m a
70+-- | Modifies the state inside a state monad.
66−gets proxy f = fmap f (get proxy)
67−
68modify :: MonadState tag s m => proxy tag -> (s -> s) -> m ()
71modify :: MonadState tag s m => proxy tag -> (s -> s) -> m ()
69modify proxy f = state proxy $ \ s -> ((), f s)
72modify proxy f = state proxy $ \ s -> ((), f s)
70
73
74+-- | Gets specific component of the state, using a projection function supplied.
75+gets :: MonadState tag s m => proxy tag -> (s -> a) -> m a
76+gets proxy f = fmap f (get proxy)
77+
71instance {-# OVERLAPPING #-} Monad m => MonadState tag s (StateT tag s m) where
78instance {-# OVERLAPPING #-} Monad m => MonadState tag s (StateT tag s m) where
72 get proxy = stateT proxy (\s -> return (s, s))
79 get proxy = stateT proxy (\s -> return (s, s))
73 put proxy s = stateT proxy (\_ -> return ((), s))
80 put proxy s = stateT proxy (\_ -> return ((), s))
src/Control/Monad/Trans/Ether/Reader.hs+5−3
@@ -63,15 +63,17 @@ type instance Tags (ReaderT tag r m) = tag ': Tags m
63readerT :: proxy tag -> (r -> m a) -> ReaderT tag r m a
63readerT :: proxy tag -> (r -> m a) -> ReaderT tag r m a
64readerT _proxy = ReaderT . Trans.ReaderT
64readerT _proxy = ReaderT . Trans.ReaderT
65
65
66−-- | Runs a 'Reader' and extracts the final value from it.
66+-- | Runs a 'ReaderT' with the given environment
67+-- and returns the vinal value.
67runReaderT :: proxy tag -> ReaderT tag r m a -> r -> m a
68runReaderT :: proxy tag -> ReaderT tag r m a -> r -> m a
68runReaderT _proxy (ReaderT (Trans.ReaderT f)) = f
69runReaderT _proxy (ReaderT (Trans.ReaderT f)) = f
69
70
70−-- | Runs a 'Reader' and extracts the final value from it.
71+-- | Runs a 'ReaderT' with the given environment
72+-- and returns the vinal value.
71runReader :: proxy tag -> Reader tag r a -> r -> a
73runReader :: proxy tag -> Reader tag r a -> r -> a
72runReader proxy m r = runIdentity (runReaderT proxy m r)
74runReader proxy m r = runIdentity (runReaderT proxy m r)
73
75
74−-- | Transform the computation inside a @ReaderT@.
76+-- | Transform the computation inside a 'ReaderT'.
75--
77--
76-- * @'runReaderT' tag ('mapReaderT' tag f m) = f . 'runReaderT' tag m@
78-- * @'runReaderT' tag ('mapReaderT' tag f m) = f . 'runReaderT' tag m@
77mapReaderT :: proxy tag -> (m a -> n b) -> ReaderT tag r m a -> ReaderT tag r n b
79mapReaderT :: proxy tag -> (m a -> n b) -> ReaderT tag r m a -> ReaderT tag r n b
src/Control/Monad/Trans/Ether/State.hs+56−17
@@ -7,16 +7,20 @@
7{-# LANGUAGE TypeOperators #-}
7{-# LANGUAGE TypeOperators #-}
8{-# LANGUAGE GeneralizedNewtypeDeriving #-}
8{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9module Control.Monad.Trans.Ether.State
9module Control.Monad.Trans.Ether.State
10− ( StateT
10+ (
11− , State
11+ -- * The State monad
12− , runStateT
12+ State
13 , runState
13 , runState
14− , evalStateT
15 , evalState
14 , evalState
16− , execStateT
17 , execState
15 , execState
16+ -- * The StateT monad transformer
17+ , StateT
18 , stateT
18 , stateT
19+ , runStateT
20+ , evalStateT
21+ , execStateT
19 , mapStateT
22 , mapStateT
23+ -- * Litfing other operations
20 , liftCatch
24 , liftCatch
21 , liftCallCC'
25 , liftCallCC'
22 , liftListen
26 , liftListen
@@ -42,47 +46,82 @@ import qualified Control.Monad.State.Class as Class
42import qualified Control.Monad.Writer.Class as Class
46import qualified Control.Monad.Writer.Class as Class
43import qualified Control.Monad.Error.Class as Class
47import qualified Control.Monad.Error.Class as Class
44
48
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.
45newtype StateT tag s m a = StateT (Trans.StateT s m a)
64newtype StateT tag s m a = StateT (Trans.StateT s m a)
46 deriving ( Functor, Applicative, Alternative, Monad, MonadPlus
65 deriving ( Functor, Applicative, Alternative, Monad, MonadPlus
47 , MonadFix, MonadTrans, MonadIO )
66 , MonadFix, MonadTrans, MonadIO )
48
67
49type instance Tags (StateT tag r m) = tag ': Tags m
68type instance Tags (StateT tag r m) = tag ': Tags m
50
69
51−type State tag r = StateT tag r Identity
70+-- | Constructor for computations in the state monad transformer.
52−
53stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
71stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
54stateT _proxy = StateT . Trans.StateT
72stateT _proxy = StateT . Trans.StateT
55
73
74+-- | Runs a 'StateT' with the given initial state
75+-- and returns both the final value and the final state.
56runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
76runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
57runStateT _proxy (StateT (Trans.StateT f)) = f
77runStateT _proxy (StateT (Trans.StateT f)) = f
58
78
59−runState :: proxy tag -> State tag s a -> s -> (a, s)
79+-- | Runs a 'StateT' with the given initial state
60−runState proxy m s = runIdentity (runStateT proxy m s)
80+-- and returns the final value, discarding the final state.
61−
62evalStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m a
81evalStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m a
63evalStateT proxy m s = fmap fst (runStateT proxy m s)
82evalStateT proxy m s = fmap fst (runStateT proxy m s)
64
83
65−evalState :: proxy tag -> State tag s a -> s -> a
84+-- | Runs a 'StateT' with the given initial state
66−evalState proxy m s = fst (runState proxy m s)
85+-- and returns the final state, discarding the final value.
67−
68execStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m s
86execStateT :: Functor m => proxy tag -> StateT tag s m a -> s -> m s
69execStateT proxy m s = fmap snd (runStateT proxy m s)
87execStateT proxy m s = fmap snd (runStateT proxy m s)
70
88
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.
71execState :: proxy tag -> State tag s a -> s -> s
101execState :: 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)
73
103
104+-- | Transform the computation inside a 'StateT'.
105+--
106+-- * @'runStateT' tag ('mapStateT' tag f m) = f . 'runStateT' tag m@
74mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
107mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
75mapStateT _proxy f m = StateT $ Trans.mapStateT f (coerce m)
108mapStateT _proxy f m = StateT $ Trans.mapStateT f (coerce m)
76
109
110+-- | Lift a @catchE@ operation to the new monad.
77liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
111liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
78liftCatch _proxy f m h = StateT $ Trans.liftCatch f (coerce m) (coerce h)
112liftCatch _proxy f m h = StateT $ Trans.liftCatch f (coerce m) (coerce h)
79
113
80−liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
114+-- | Lift a @listen@ operation to the new monad.
81−liftCallCC' _proxy callCC f = StateT $ Trans.liftCallCC' callCC (coerce f)
82−
83liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
115liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
84liftListen _proxy listen m = StateT $ Trans.liftListen listen (coerce m)
116liftListen _proxy listen m = StateT $ Trans.liftListen listen (coerce m)
85
117
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.
86liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
125liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
87liftPass _proxy pass m = StateT $ Trans.liftPass pass (coerce m)
126liftPass _proxy pass m = StateT $ Trans.liftPass pass (coerce m)
88
127