2c4c0efe0d1b5a04d7a4371238483d47bc15039d
[ghc-hetmet.git] / ghc / lib / std / Monad.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1999
3 %
4 \section[Monad]{Module @Monad@}
5
6 \begin{code}
7 module Monad 
8     ( MonadPlus (   -- class context: Monad
9           mzero     -- :: (MonadPlus m) => m a
10         , mplus     -- :: (MonadPlus m) => m a -> m a -> m a
11         )
12     , join          -- :: (Monad m) => m (m a) -> m a
13     , guard         -- :: (MonadPlus m) => Bool -> m ()
14     , when          -- :: (Monad m) => Bool -> m () -> m ()
15     , unless        -- :: (Monad m) => Bool -> m () -> m ()
16     , ap            -- :: (Monad m) => (m (a -> b)) -> (m a) -> m b
17     , msum          -- :: (MonadPlus m) => [m a] -> m a
18     , filterM       -- :: (Monad m) => (a -> m Bool) -> [m a] -> m [a]
19     , mapAndUnzipM  -- :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
20     , zipWithM      -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
21     , zipWithM_     -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
22     , foldM         -- :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a 
23     
24     , liftM         -- :: (Monad m) => (a -> b) -> (m a -> m b)
25     , liftM2        -- :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)
26     , liftM3        -- :: ...
27     , liftM4        -- :: ...
28     , liftM5        -- :: ...
29
30     , Monad((>>=), (>>), return, fail)
31     , Functor(fmap)
32
33     , mapM          -- :: (Monad m) => (a -> m b) -> [a] -> m [b]
34     , mapM_         -- :: (Monad m) => (a -> m b) -> [a] -> m ()
35     , sequence      -- :: (Monad m) => [m a] -> m [a]
36     , sequence_     -- :: (Monad m) => [m a] -> m ()
37     , (=<<)         -- :: (Monad m) => (a -> m b) -> m a -> m b
38     ) where
39
40 import Prelude
41 \end{code}
42
43 %*********************************************************
44 %*                                                      *
45 \subsection{Monadic classes: @MonadPlus@}
46 %*                                                      *
47 %*********************************************************
48
49
50 \begin{code}
51 class Monad m => MonadPlus m where
52   mzero :: m a
53   mplus :: m a -> m a -> m a
54
55 instance MonadPlus [] where
56    mzero = []
57    mplus = (++)
58
59 instance MonadPlus Maybe where
60    mzero = Nothing
61
62    Nothing `mplus` ys  = ys
63    xs      `mplus` _ys = xs
64 \end{code}
65
66
67 %*********************************************************
68 %*                                                      *
69 \subsection{Functions mandated by the Prelude}
70 %*                                                      *
71 %*********************************************************
72
73 \begin{code}
74 guard           :: MonadPlus m => Bool -> m ()
75 guard pred
76  | pred      = return ()
77  | otherwise = mzero
78
79 -- This subsumes the list-based filter function.
80
81 filterM         :: (Monad m) => ( a -> m Bool ) -> [a] -> m [a]
82 filterM _predM []     = return []
83 filterM  predM (x:xs) = do
84    flg <- predM x
85    ys  <- filterM predM xs
86    return (if flg then x:ys else ys)
87
88 -- This subsumes the list-based concat function.
89
90 msum        :: MonadPlus m => [m a] -> m a
91 {-# INLINE msum #-}
92 msum        =  foldr mplus mzero
93 \end{code}
94
95
96 %*********************************************************
97 %*                                                      *
98 \subsection{Other monad functions}
99 %*                                                      *
100 %*********************************************************
101
102 \begin{code}
103 join             :: (Monad m) => m (m a) -> m a
104 join x           = x >>= id
105
106 mapAndUnzipM     :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
107 mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip
108
109 zipWithM         :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
110 zipWithM f xs ys = sequence (zipWith f xs ys)
111
112 zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
113 zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
114
115 foldM            :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
116 foldM _ a []     = return a
117 foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
118
119 unless           :: (Monad m) => Bool -> m () -> m ()
120 unless p s       =  if p then return () else s
121
122 when             :: (Monad m) => Bool -> m () -> m ()
123 when p s         =  if p then s else return ()
124
125 ap :: (Monad m) => m (a->b) -> m a -> m b
126 ap = liftM2 ($)
127
128 liftM   :: (Monad m) => (a1 -> r) -> m a1 -> m r
129 liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
130 liftM3  :: (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
131 liftM4  :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
132 liftM5  :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
133
134 liftM f m1              = do { x1 <- m1; return (f x1) }
135 liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
136 liftM3 f m1 m2 m3       = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
137 liftM4 f m1 m2 m3 m4    = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f x1 x2 x3 x4) }
138 liftM5 f m1 m2 m3 m4 m5 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; x5 <- m5; return (f x1 x2 x3 x4 x5) }
139
140 \end{code}