There is a few ways you can speak of "the WHY of monads". Most basically, monads are one way of 1) combining things 2) which (may) produce a value, 3) where which things you combine in later may depend on earlier values produced.

Why do we speak of them, as opposed to just combining things in that way when we happen to? Partly, for the reasons people generally speak of design patterns: it's one fewer degree of freedom in your design which makes it easier to reason about and when others know the pattern it is easier to communicate what you are doing to them. In one-off cases, in most languages with (comparatively) limited powers of abstraction, this is most of what's useful about saying "hey, that's a monad!".

In Haskell, "Monad" is also an interface for things that fit that pattern, and we have a lot of functions that operate against that interface to do useful things, so that we don't need to rewrite those things for each new thing that happens to be a monad.

For instance:

mapM :: Monad m => (a -> m b) -> [a] -> m [b]

which is like map, but takes a function that returns a monadic value instead of any function, and instead of producing a list of those monadic values it stitches together the values and gives you a wrapped list of the values. To drive intuition, we can specialize this for a few individual monads:

mapM :: (a -> Maybe b) -> [a] -> Maybe [b]

Maybe. Pass it a function that may fail, and a list of values to feed into that function, and it will give you "Just" a list of the results or "Nothing" if any function fails.

mapM :: (a -> Identity b) -> [a] -> Identity [b]

Identity. As you would pretty much expect, this is isomorphic to map. Not a lot of reason to do this unless you've got some other function you care about which is expecting something of this form and you want to basically pass map.

mapM :: (a -> [b]) -> [a] -> [[b]]

List. The list monad is for nondeterminism - "take every path". I... don't immediately see a good use for mapM in list - something like concatMap is much more useful - but if you ever have a need for it...

mapM :: (a -> IO b) -> [a] -> IO [b]

IO. Pass in a function that returns an IO action, and a list of parameters for that function, and give back an IO action that produces a list of the results. A simple example:

mapM (\ l -> putStr (l ++ ": ") >> fmap (l,) getLine) ["height", "weight"]

This would have the type

IO [(String, String)]

and would, when executed, prompt the user for height and weight in turn, and return a list of tuples containing both the label and the response. You can see how you could trivially add "age".

mapM :: (a -> State s b) -> [a] -> State s [b]

State. State actions operate on an additional piece of data that's carried around and threaded through the chain of binds. This specialization of mapM takes a function that produces actions which use or modify state, threads them together into one big such action.

mapM :: (a -> Parser b) -> [a] -> Parser [b]

Parser, from the wonderful attoparsec. Here, we pass in a function that generates parsers, and a list of inputs to that function, and get a parser that parses a list!

There are a ton more similarly abstract, comparably useful functions, some of which are in http://hackage.haskell.org/package/base-4.6.0.1/docs/Control... - and you can always write something new when there's a pattern you want to exploit for which a combinator doesn't exist. All of this - both the implementations of the monads (except the internals of IO) and the functions that operate on them - is written in ordinary Haskell. You can check out the source on Hackage, if you're curious as to how.

mapM is implemented:

mapM f as = sequence (map f as)

If we inline sequence, that becomes:

mapM f as = foldr k (return []) ms
where
k m m' = do { x <- m; xs <- m'; return (x:xs) }

We can strip out the do notation:

mapM f as = foldr k (return []) ms
where
k m m' = m >>= (\ x -> m' >>= (\ xs -> return (x:xs)))

where it should be somewhat apparent there's not actually any voodoo.