3a_asm: adding some libraries, in order to be compatible with the tilab environment
[calu.git] / 3a_asm / Control / Monad / Writer / Class.hs
1 {-# LANGUAGE UndecidableInstances #-}
2 -- Search for UndecidableInstances to see why this is needed
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module      :  Control.Monad.Writer.Class
7 -- Copyright   :  (c) Andy Gill 2001,
8 --                (c) Oregon Graduate Institute of Science and Technology, 2001
9 -- License     :  BSD-style (see the file libraries/base/LICENSE)
10 --
11 -- Maintainer  :  libraries@haskell.org
12 -- Stability   :  experimental
13 -- Portability :  non-portable (multi-param classes, functional dependencies)
14 --
15 -- The MonadWriter class.
16 --
17 --      Inspired by the paper
18 --      /Functional Programming with Overloading and
19 --          Higher-Order Polymorphism/,
20 --        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>)
21 --          Advanced School of Functional Programming, 1995.
22 -----------------------------------------------------------------------------
23
24 module Control.Monad.Writer.Class (
25     MonadWriter(..),
26     listens,
27     censor,
28   ) where
29
30 import Data.Monoid
31
32 -- ---------------------------------------------------------------------------
33 -- MonadWriter class
34 --
35 -- tell is like tell on the MUD's it shouts to monad
36 -- what you want to be heard. The monad carries this 'packet'
37 -- upwards, merging it if needed (hence the Monoid requirement)}
38 --
39 -- listen listens to a monad acting, and returns what the monad "said".
40 --
41 -- pass lets you provide a writer transformer which changes internals of
42 -- the written object.
43
44 class (Monoid w, Monad m) => MonadWriter w m | m -> w where
45     tell   :: w -> m ()
46     listen :: m a -> m (a, w)
47     pass   :: m (a, w -> w) -> m a
48
49 listens :: (MonadWriter w m) => (w -> b) -> m a -> m (a, b)
50 listens f m = do
51     ~(a, w) <- listen m
52     return (a, f w)
53
54 censor :: (MonadWriter w m) => (w -> w) -> m a -> m a
55 censor f m = pass $ do
56     a <- m
57     return (a, f)
58