2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[Monad]{Module @Monad@}
7 {-# OPTIONS -fno-implicit-prelude #-}
11 Monad(..), MonadZero(..), MonadPlus(..),
13 -- Prelude monad functions
15 mapM, mapM_, guard, filter, concat, applyM,
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
36 %*********************************************************
38 \subsection{Functions mandated by the Prelude}
40 %*********************************************************
43 accumulate :: Monad m => [m a] -> m [a]
44 accumulate [] = return []
45 accumulate (m:ms) = do { x <- m; xs <- accumulate ms; return (x:xs) }
47 sequence :: Monad m => [m a] -> m ()
48 sequence = foldr (>>) (return ())
50 mapM :: Monad m => (a -> m b) -> [a] -> m [b]
51 mapM f as = accumulate (map f as)
53 mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
54 mapM_ f as = sequence (map f as)
56 guard :: MonadZero m => Bool -> m ()
57 guard p = if p then return () else zero
59 -- This subsumes the list-based filter function.
61 filter :: MonadZero m => (a -> Bool) -> m a -> m a
62 filter p = applyM (\x -> if p x then return x else zero)
64 -- This subsumes the list-based concat function.
66 concat :: MonadPlus m => [m a] -> m a
67 concat = foldr (++) zero
69 applyM :: Monad m => (a -> m b) -> m a -> m b
74 %*********************************************************
76 \subsection{Other monad functions}
78 %*********************************************************
81 join :: (Monad m) => m (m a) -> m a
84 mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
85 mapAndUnzipM f xs = accumulate (map f xs) >>= return . unzip
87 zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
88 zipWithM f xs ys = accumulate (zipWith f xs ys)
90 zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
91 zipWithM_ f xs ys = sequence (zipWith f xs ys)
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
97 unless :: (Monad m) => Bool -> m () -> m ()
98 unless p s = if p then return () else s
100 when :: (Monad m) => Bool -> m () -> m ()
101 when p s = if p then s else return ()
103 ap :: (Monad m) => m (a->b) -> m a -> m b
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
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) }