@@ -9,6 +9,18 @@ import Control.Monad.Trans
9import Data.Functor.Identity
9import Data.Functor.Identity
10import Data.Monoid
10import Data.Monoid
12+-- | A declare monad transformer parametrized by:
14+-- * @d@ — the output to accumulate (declarations);
16+-- * @m@ — the inner monad.
18+-- This monad transformer is similar to both state and writer monad transformers.
19+-- Thus it can be seen as
21+-- * a restricted append-only version of a state monad transformer or
23+-- * a writer monad transformer with the extra ability to read all previous output.
12newtype DeclareT d m a = DeclareT { runDeclareT :: d -> m (d, a) }
24newtype DeclareT d m a = DeclareT { runDeclareT :: d -> m (d, a) }
13 deriving (Functor)
25 deriving (Functor)
@@ -29,14 +41,28 @@ instance (Monad m, Monoid d) => Monad (DeclareT d m) where
29instance Monoid d => MonadTrans (DeclareT d) where
41instance Monoid d => MonadTrans (DeclareT d) where
30 lift m = DeclareT (\_ -> (,) mempty <$> m)
42 lift m = DeclareT (\_ -> (,) mempty <$> m)
48+-- declare mempty == return ()
49+-- declare x >> declare y == declare (x <> y)
51+-- declare x >> look == fmap (<> x) look
32class Monad m => MonadDeclare d m | m -> d where
55class Monad m => MonadDeclare d m | m -> d where
56+ -- | @'declare' x@ is an action that produces the output @x@.
33 declare :: d -> m ()
57 declare :: d -> m ()
58+ -- | @'look'@ is an action that returns all the output so far.
34 look :: m d
59 look :: m d
36instance (Monad m, Monoid d) => MonadDeclare d (DeclareT d m) where
61instance (Monad m, Monoid d) => MonadDeclare d (DeclareT d m) where
37 declare d = DeclareT (\_ -> return (d, ()))
62 declare d = DeclareT (\_ -> return (d, ()))
38 look = DeclareT (\d -> return (mempty, d))
63 look = DeclareT (\d -> return (mempty, d))
65+-- | Retrieve a function of all the output so far.
40looks :: MonadDeclare d m => (d -> a) -> m a
66looks :: MonadDeclare d m => (d -> a) -> m a
41looks f = f <$> look
67looks f = f <$> look
@@ -49,6 +75,14 @@ execDeclareT (DeclareT f) d = fst `liftM` f d
49undeclareT :: (Monad m, Monoid d) => DeclareT d m a -> m a
75undeclareT :: (Monad m, Monoid d) => DeclareT d m a -> m a
50undeclareT = flip evalDeclareT mempty
76undeclareT = flip evalDeclareT mempty
78+-- | A declare monad parametrized by @d@ — the output to accumulate (declarations).
80+-- This monad is similar to both state and writer monads.
81+-- Thus it can be seen as
83+-- * a restricted append-only version of a state monad or
85+-- * a writer monad with the extra ability to read all previous output.
52type Declare d = DeclareT d Identity
86type Declare d = DeclareT d Identity
54runDeclare :: Declare d a -> d -> (d, a)
88runDeclare :: Declare d a -> d -> (d, a)