module Monad ( join, mapAndUnzipM, zipWithM, foldM, when, unless, ap, liftM, liftM2, liftM3, liftM4, liftM5 ) where join :: (Monad m) => m (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] foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a zeroOrMore :: (MonadPlus m) => m a -> m [a] oneOrMore :: (MonadPlus m) => m a -> m [a] when :: (Monad m) => Bool -> m () -> m () unless :: (Monad m) => Bool -> m () -> m () ap :: (Monad a) => (m (a -> b)) -> (m a) -> m b liftM :: (Monad m) => (a -> b) -> (m a -> m b) liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) liftM3 :: (Monad m) => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d) liftM4 :: (Monad m) => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e) liftM5 :: (Monad m) => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f) |
These utilities provide some useful operations on monads.
The join function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.
The mapAndUnzipM function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state-transforming monad.
The zipWithM function generalises zipWith to arbitrary monads.
For instance the following function displays a file, prefixing
each line with its line number,
listFile :: String -> IO ()
listFile nm =
do cts <- openFile nm
zipWithM_ (\i line -> do putStr (show i); putStr ": "; putStrLn line)
[1..]
(lines cts)
The foldM function is analogous to foldl, except that its result
is encapsulated in a monad. Note that foldM works from
left-to-right over the list arguments. This could be an issue where
(>>) and the "folded function" are not commutative.
foldM f a1 [x1, x2, ..., xm ]
==
do
a2 <- f a1 x1
a3 <- f a2 x2
...
f am xm
If right-to-left
evaluation is required, the input list should be reversed.
The when and unless functions provide conditional execution of
monadic expressions. For example,
when debug (putStr "Debugging\n")
will output the string "Debugging\n" if the Boolean value debug is
True, and otherwise do nothing.
The monadic lifting operators promote a function to a monad. The
function arguments are scanned left to right. For example,
liftM2 (+) [0,1] [0,2] = [0,2,1,3]
liftM2 (+) (Just 1) Nothing = Nothing
In many situations, the liftM operations can be replaced by uses
of ap, which promotes function application.
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftMn f x1 x2 ... xn