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