    -- |
    -- The "Control.Monad" module provides the 'Functor', 'Monad' and
    -- 'MonadPlus' classes, together with some useful operations on monads.

    module Control.Monad (
        -- * Functor and monad classes

          Functor(fmap)
        , Monad((>>=), (>>), return, fail)

        , MonadPlus (   -- class context: Monad
              mzero     -- :: (MonadPlus m) => m a
            , mplus     -- :: (MonadPlus m) => m a -> m a -> m a
            )
        -- * Functions

        -- ** Naming conventions
        -- $naming

        -- ** Basic @Monad@ functions

        , mapM          -- :: (Monad m) => (a -> m b) -> [a] -> m [b]
        , mapM_         -- :: (Monad m) => (a -> m b) -> [a] -> m ()
        , forM          -- :: (Monad m) => [a] -> (a -> m b) -> m [b]
        , forM_         -- :: (Monad m) => [a] -> (a -> m b) -> m ()
        , sequence      -- :: (Monad m) => [m a] -> m [a]
        , sequence_     -- :: (Monad m) => [m a] -> m ()
        , (=<<)         -- :: (Monad m) => (a -> m b) -> m a -> m b
        , (>=>)         -- :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)
        , (<=<)         -- :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
        , forever       -- :: (Monad m) => m a -> m b
        , void

        -- ** Generalisations of list functions

        , join          -- :: (Monad m) => m (m a) -> m a
        , 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 ()
        , replicateM    -- :: (Monad m) => Int -> m a -> m [a]
        , replicateM_   -- :: (Monad m) => Int -> m a -> m ()

        -- ** Conditional execution of monadic expressions

        , guard         -- :: (MonadPlus m) => Bool -> m ()
        , when          -- :: (Monad m) => Bool -> m () -> m ()
        , unless        -- :: (Monad m) => Bool -> m () -> m ()

        -- ** Monadic lifting operators

        , liftM         -- :: (Monad m) => (a -> b) -> (m a -> m b)
        , liftM2        -- :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c)
        , liftM3        -- :: ...
        , liftM4        -- :: ...
        , liftM5        -- :: ...

        , ap            -- :: (Monad m) => m (a -> b) -> m a -> m b

      ) where
    import "base" Control.Monad

    {- $naming

    The functions in this library use the following naming conventions:

    * A postfix \'@M@\' always stands for a function in the Kleisli category:
      The monad type constructor @m@ is added to function results
      (modulo currying) and nowhere else.  So, for example,

    >  filter  ::              (a ->   Bool) -> [a] ->   [a]
    >  filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]

    * A postfix \'@_@\' changes the result type from @(m a)@ to @(m ())@.
      Thus, for example:

    >  sequence  :: Monad m => [m a] -> m [a]
    >  sequence_ :: Monad m => [m a] -> m ()

    * A prefix \'@m@\' generalizes an existing function to a monadic form.
      Thus, for example:

    >  sum  :: Num a       => [a]   -> a
    >  msum :: MonadPlus m => [m a] -> m a

    -}