2be1dba4394fc8d849baf7ca7e31dc80083cda00
[ghc-hetmet.git] / ghc / lib / required / Monad.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1996
3 %
4 \section[Monad]{Module @Monad@}
5
6 \begin{code}
7 {-# OPTIONS -fno-implicit-prelude #-}
8
9 module Monad (
10     Functor(..), 
11     Monad(..), MonadZero(..), MonadPlus(..),
12
13     -- Prelude monad functions
14     accumulate, sequence, 
15     mapM, mapM_, guard, filter, concat, applyM,
16
17     -- Standard Monad interface:
18     join,           -- :: (Monad m) => m (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     when,           -- :: (Monad m) => Bool -> m () -> m ()
24     unless,         -- :: (Monad m) => Bool -> m () -> m ()
25     ap,             -- :: (Monad m) => (m (a -> b)) -> (m a) -> m b
26     liftM, liftM2,  
27     liftM3, liftM4, 
28     liftM5
29   ) where
30
31 import PrelList
32 import PrelTup
33 import PrelBase
34 \end{code}
35
36 %*********************************************************
37 %*                                                      *
38 \subsection{Functions mandated by the Prelude}
39 %*                                                      *
40 %*********************************************************
41
42 \begin{code}
43 accumulate      :: Monad m => [m a] -> m [a] 
44 accumulate []     = return []
45 accumulate (m:ms) = do { x <- m; xs <- accumulate ms; return (x:xs) }
46
47 sequence        :: Monad m => [m a] -> m () 
48 sequence        =  foldr (>>) (return ())
49
50 mapM            :: Monad m => (a -> m b) -> [a] -> m [b]
51 mapM f as       =  accumulate (map f as)
52
53 mapM_           :: Monad m => (a -> m b) -> [a] -> m ()
54 mapM_ f as      =  sequence (map f as)
55
56 guard           :: MonadZero m => Bool -> m ()
57 guard p         =  if p then return () else zero
58
59 -- This subsumes the list-based filter function.
60
61 filter          :: MonadZero m => (a -> Bool) -> m a -> m a
62 filter p        =  applyM (\x -> if p x then return x else zero)
63
64 -- This subsumes the list-based concat function.
65
66 concat          :: MonadPlus m => [m a] -> m a
67 concat          =  foldr (++) zero
68  
69 applyM          :: Monad m => (a -> m b) -> m a -> m b
70 applyM f x      =  x >>= f
71 \end{code}
72
73
74 %*********************************************************
75 %*                                                      *
76 \subsection{Other monad functions}
77 %*                                                      *
78 %*********************************************************
79
80 \begin{code}
81 join             :: (Monad m) => m (m a) -> m a
82 join x           = x >>= id
83
84 mapAndUnzipM     :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
85 mapAndUnzipM f xs = accumulate (map f xs) >>= return . unzip
86
87 zipWithM         :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
88 zipWithM f xs ys = accumulate (zipWith f xs ys)
89
90 zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
91 zipWithM_ f xs ys = sequence (zipWith f xs ys)
92
93 foldM            :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
94 foldM f a []     = return a
95 foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
96
97 unless           :: (Monad m) => Bool -> m () -> m ()
98 unless p s       =  if p then return () else s
99
100 when             :: (Monad m) => Bool -> m () -> m ()
101 when p s         =  if p then s else return ()
102
103 ap :: (Monad m) => m (a->b) -> m a -> m b
104 ap = liftM2 ($)
105
106 liftM   :: (Monad m) => (a1 -> r) -> m a1 -> m r
107 liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
108 liftM3  :: (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
109 liftM4  :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
110 liftM5  :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
111
112 liftM f m1              = do { x1 <- m1; return (f x1) }
113 liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
114 liftM3 f m1 m2 m3       = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
115 liftM4 f m1 m2 m3 m4    = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f x1 x2 x3 x4) }
116 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) }
117
118 \end{code}