+% -----------------------------------------------------------------------------
+% $Id: Monad.lhs,v 1.13 2001/05/18 16:54:05 simonmar Exp $
%
-% (c) The AQUA Project, Glasgow University, 1994-1999
+% (c) The University of Glasgow, 1994-2000
%
+
\section[Monad]{Module @Monad@}
\begin{code}
mzero -- :: (MonadPlus m) => m a
, mplus -- :: (MonadPlus m) => m a -> m a -> m a
)
- , join -- :: (Monad m) => m (m a) -> m a
- , guard -- :: (Monad m) => Bool -> m ()
- , when -- :: (Monad m) => Bool -> m () -> m ()
- , unless -- :: (Monad m) => Bool -> m () -> m ()
- , ap -- :: (Monad m) => (m (a -> b)) -> (m a) -> m b
- , msum -- :: (MonadPlus m) => [m a] -> m a
- , filterM -- :: (Monad m) => (a -> m Bool) -> [m a] -> m [a]
- , mapAndUnzipM -- :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
- , zipWithM -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
+ , join -- :: (Monad m) => m (m a) -> m a
+ , guard -- :: (MonadPlus m) => Bool -> m ()
+ , when -- :: (Monad m) => Bool -> m () -> m ()
+ , unless -- :: (Monad m) => Bool -> m () -> m ()
+ , ap -- :: (Monad m) => m (a -> b) -> m a -> m b
+ , msum -- :: (MonadPlus m) => [m a] -> m a
+ , filterM -- :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
+ , mapAndUnzipM -- :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
+ , zipWithM -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
, zipWithM_ -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
- , foldM -- :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
+ , foldM -- :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
- , liftM -- :: (Monad m) => (a -> b) -> (m a -> m b)
- , liftM2 -- :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)
+ , liftM -- :: (Monad m) => (a -> b) -> (m a -> m b)
+ , liftM2 -- :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)
, liftM3 -- :: ...
, liftM4 -- :: ...
, liftM5 -- :: ...
, Monad((>>=), (>>), return, fail)
, Functor(fmap)
- , mapM -- :: (Monad m) => (a -> m b) -> [a] -> m [b]
- , mapM_ -- :: (Monad m) => (a -> m b) -> [a] -> m ()
- , sequence -- :: (Monad m) => [m a] -> m [a]
+ , mapM -- :: (Monad m) => (a -> m b) -> [a] -> m [b]
+ , mapM_ -- :: (Monad m) => (a -> m b) -> [a] -> m ()
+ , sequence -- :: (Monad m) => [m a] -> m [a]
, sequence_ -- :: (Monad m) => [m a] -> m ()
, (=<<) -- :: (Monad m) => (a -> m b) -> m a -> m b
) where
import PrelList
-import PrelTup
+import PrelMaybe
import PrelBase
-import PrelMaybe ( Maybe(..) )
+
+infixr 1 =<<
+\end{code}
+
+%*********************************************************
+%* *
+\subsection{Prelude monad functions}
+%* *
+%*********************************************************
+
+\begin{code}
+{-# SPECIALISE (=<<) :: (a -> [b]) -> [a] -> [b] #-}
+(=<<) :: Monad m => (a -> m b) -> m a -> m b
+f =<< x = x >>= f
+
+sequence :: Monad m => [m a] -> m [a]
+{-# INLINE sequence #-}
+sequence ms = foldr k (return []) ms
+ where
+ k m m' = do { x <- m; xs <- m'; return (x:xs) }
+
+sequence_ :: Monad m => [m a] -> m ()
+{-# INLINE sequence_ #-}
+sequence_ ms = foldr (>>) (return ()) ms
+
+mapM :: Monad m => (a -> m b) -> [a] -> m [b]
+{-# INLINE mapM #-}
+mapM f as = sequence (map f as)
+
+mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
+{-# INLINE mapM_ #-}
+mapM_ f as = sequence_ (map f as)
\end{code}
%*********************************************************
\begin{code}
class Monad m => MonadPlus m where
- mzero :: m a
- mplus :: m a -> m a -> m a
+ mzero :: m a
+ mplus :: m a -> m a -> m a
instance MonadPlus [] where
mzero = []
%*********************************************************
\begin{code}
-sequence :: Monad m => [m a] -> m [a]
-sequence [] = return []
-sequence (m:ms) = do { x <- m; xs <- sequence ms; return (x:xs) }
-
-sequence_ :: Monad m => [m a] -> m ()
-sequence_ = foldr (>>) (return ())
-
-mapM :: Monad m => (a -> m b) -> [a] -> m [b]
-mapM f as = sequence (map f as)
-
-mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
-mapM_ f as = sequence_ (map f as)
-
-guard :: MonadPlus m => Bool -> m ()
-guard pred
- | pred = return ()
- | otherwise = mzero
+guard :: (MonadPlus m) => Bool -> m ()
+guard True = return ()
+guard False = mzero
-- This subsumes the list-based filter function.
-filterM :: (Monad m) => ( a -> m Bool ) -> [a] -> m [a]
-filterM _predM [] = return []
-filterM predM (x:xs) = do
- flg <- predM x
- ys <- filterM predM xs
+filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
+filterM _ [] = return []
+filterM p (x:xs) = do
+ flg <- p x
+ ys <- filterM p xs
return (if flg then x:ys else ys)
-- This subsumes the list-based concat function.
msum :: MonadPlus m => [m a] -> m a
+{-# INLINE msum #-}
msum = foldr mplus mzero
-
-{-# SPECIALISE (=<<) :: (a -> [b]) -> [a] -> [b] #-}
-(=<<) :: Monad m => (a -> m b) -> m a -> m b
-f =<< x = x >>= f
\end{code}
%*********************************************************
-%* *
+% *
\subsection{Other monad functions}
%* *
%*********************************************************
\begin{code}
-join :: (Monad m) => m (m a) -> m a
-join x = x >>= id
+join :: (Monad m) => m (m a) -> m a
+join x = x >>= id
-mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
-mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip
+mapAndUnzipM :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
+mapAndUnzipM f xs = sequence (map f xs) >>= return . unzip
-zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
-zipWithM f xs ys = sequence (zipWith f xs ys)
+zipWithM :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
+zipWithM f xs ys = sequence (zipWith f xs ys)
-zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
-zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
+zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
+zipWithM_ f xs ys = sequence_ (zipWith f xs ys)
-foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
-foldM _ a [] = return a
-foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
+foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
+foldM _ a [] = return a
+foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
-unless :: (Monad m) => Bool -> m () -> m ()
-unless p s = if p then return () else s
+unless :: (Monad m) => Bool -> m () -> m ()
+unless p s = if p then return () else s
-when :: (Monad m) => Bool -> m () -> m ()
-when p s = if p then s else return ()
+when :: (Monad m) => Bool -> m () -> m ()
+when p s = if p then s else return ()
-ap :: (Monad m) => m (a->b) -> m a -> m b
-ap = liftM2 ($)
+ap :: (Monad m) => m (a -> b) -> m a -> m b
+ap = liftM2 id
-liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
-liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
-liftM3 :: (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
-liftM4 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
-liftM5 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
+liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
+liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
+liftM3 :: (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
+liftM4 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
+liftM5 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
-liftM f m1 = do { x1 <- m1; return (f x1) }
-liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
-liftM3 f m1 m2 m3 = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
-liftM4 f m1 m2 m3 m4 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f x1 x2 x3 x4) }
+liftM f m1 = do { x1 <- m1; return (f x1) }
+liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
+liftM3 f m1 m2 m3 = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
+liftM4 f m1 m2 m3 m4 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f x1 x2 x3 x4) }
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) }
\end{code}