+
+{- | 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
+
+-}
+
+ap :: (Monad m) => m (a -> b) -> m a -> m b
+ap = liftM2 id
+
+
+-- -----------------------------------------------------------------------------
+-- Other MonadPlus functions
+
+-- | Direct 'MonadPlus' equivalent of 'filter'
+-- @'filter'@ = @(mfilter:: (a -> Bool) -> [a] -> [a]@
+-- applicable to any 'MonadPlus', for example
+-- @mfilter odd (Just 1) == Just 1@
+-- @mfilter odd (Just 2) == Nothing@
+
+mfilter :: (MonadPlus m) => (a -> Bool) -> m a -> m a
+mfilter p ma = do
+ a <- ma
+ if p a then return a else mzero
+
+{- $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
+
+-}