Prime -> 2010
[haskell-report.git] / report / lib-code / Monad.hs
1 module Monad (
2 MonadPlus(mzero, mplus),
3 join, guard, when, unless, ap,
4 msum,
5 filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM,
6 liftM, liftM2, liftM3, liftM4, liftM5,
7
8 -- ...and what the Prelude exports
9 Monad((>>=), (>>), return, fail),
10 Functor(fmap),
11 mapM, mapM_, sequence, sequence_, (=<<),
12 ) where
13
14
15 -- The MonadPlus class definition
16
17 class (Monad m) => MonadPlus m where
18 mzero :: m a
19 mplus :: m a -> m a -> m a
20
21
22 -- Instances of MonadPlus
23
24 instance MonadPlus Maybe where
25 mzero = Nothing
26
27 Nothing `mplus` ys = ys
28 xs `mplus` ys = xs
29
30 instance MonadPlus [] where
31 mzero = []
32 mplus = (++)
33
34
35 -- Functions
36
37
38 msum :: MonadPlus m => [m a] -> m a
39 msum xs = foldr mplus mzero xs
40
41 join :: (Monad m) => m (m a) -> m a
42 join x = x >>= id
43
44 when :: (Monad m) => Bool -> m () -> m ()
45 when p s = if p then s else return ()
46
47 unless :: (Monad m) => Bool -> m () -> m ()
48 unless p s = when (not p) s
49
50 ap :: (Monad m) => m (a -> b) -> m a -> m b
51 ap = liftM2 ($)
52
53 guard :: MonadPlus m => Bool -> m ()
54 guard p = if p then return () else mzero
55
56 mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
57 mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip
58
59 zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
60 zipWithM f xs ys = sequence (zipWith f xs ys)
61
62 zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
63 zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
64
65 foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
66 foldM f a [] = return a
67 foldM f a (x:xs) = f a x >>= \ y -> foldM f y xs
68
69 filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
70 filterM p [] = return []
71 filterM p (x:xs) = do { b <- p x;
72 ys <- filterM p xs;
73 return (if b then (x:ys) else ys)
74 }
75
76 liftM :: (Monad m) => (a -> b) -> (m a -> m b)
77 liftM f = \a -> do { a' <- a; return (f a') }
78
79 liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)
80 liftM2 f = \a b -> do { a' <- a; b' <- b; return (f a' b') }
81
82 liftM3 :: (Monad m) => (a -> b -> c -> d) ->
83 (m a -> m b -> m c -> m d)
84 liftM3 f = \a b c -> do { a' <- a; b' <- b; c' <- c;
85 return (f a' b' c') }
86
87 liftM4 :: (Monad m) => (a -> b -> c -> d -> e) ->
88 (m a -> m b -> m c -> m d -> m e)
89 liftM4 f = \a b c d -> do { a' <- a; b' <- b; c' <- c; d' <- d;
90 return (f a' b' c' d') }
91
92 liftM5 :: (Monad m) => (a -> b -> c -> d -> e -> f) ->
93 (m a -> m b -> m c -> m d -> m e -> m f)
94 liftM5 f = \a b c d e -> do { a' <- a; b' <- b; c' <- c; d' <- d;
95 e' <- e; return (f a' b' c' d' e') }
96
97