1 -----------------------------------------------------------------------------
2 -- Standard Library: Monad operations
4 -- Suitable for use with Hugs 98
5 -----------------------------------------------------------------------------
8 MonadPlus(mzero, mplus),
9 join, guard, when, unless, ap,
11 filterM, mapAndUnzipM, zipWithM, zipWithM_, foldM,
12 liftM, liftM2, liftM3, liftM4, liftM5,
14 -- ... and what the Prelude exports
15 Monad((>>=), (>>), return, fail),
17 mapM, mapM_, accumulate, sequence, (=<<),
20 -- The MonadPlus class definition
22 class Monad m => MonadPlus m where
24 mplus :: m a -> m a -> m a
26 -- Instances of MonadPlus
28 instance MonadPlus Maybe where
30 Nothing `mplus` ys = ys
33 instance MonadPlus [ ] where
39 msum :: MonadPlus m => [m a] -> m a
40 msum = foldr mplus mzero
42 join :: (Monad m) => m (m a) -> m a
45 when :: (Monad m) => Bool -> m () -> m ()
46 when p s = if p then s else return ()
48 unless :: (Monad m) => Bool -> m () -> m ()
49 unless p s = when (not p) s
51 ap :: (Monad m) => m (a -> b) -> m a -> m b
54 guard :: MonadPlus m => Bool -> m ()
55 guard p = if p then return () else mzero
57 mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
58 mapAndUnzipM f xs = accumulate (map f xs) >>= return . unzip
60 zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
61 zipWithM f xs ys = accumulate (zipWith f xs ys)
63 zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
64 zipWithM_ f xs ys = sequence (zipWith f xs ys)
66 foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
67 foldM f a [] = return a
68 foldM f a (x:xs) = f a x >>= \ y -> foldM f y xs
70 filterM :: MonadPlus m => (a -> m Bool) -> [a] -> m [a]
71 filterM p [] = return []
72 filterM p (x:xs) = do b <- p x
74 return (if b then (x:ys) else ys)
76 liftM :: (Monad m) => (a -> b) -> (m a -> m b)
77 liftM f = \a -> do { a' <- a; return (f a') }
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') }
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;
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')}
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')}
97 -----------------------------------------------------------------------------