A monad is any construct of abstraction that obeys the Monad Laws. This may seem a useless definition, but my point is that deriving a useful intuition for the concept of the monad is necessarily challenging because they cannot readily be boiled down any further than that without loss of information.
The best intuitive explanation I've developed so far is that a monad is an abstraction over structures of ordered computations. The most ready examples for non-functional programmers are probably exceptions (and their handlers) and nullable types (typically called "optional types" in languages with first-class handling of such things, unlike Java).
This is something you see a lot once you know what you're looking for.
And if you're really lucky, these two are nicely compatible:
For example there are two ways to get from L(L(L(X))) to L(X): By either flattening first in the inside or first on the outside.
And for a monad, you get the same result either way.
And the computational part is then really more of a consequence: If you've got some function of type X->L(Y) and another one of type Y->L(Z) then you can compose them to a function of type X->L(Z).
map :: (a -> b) -> (t a -> t b) -- Functor
bind :: (a -> t b) -> (t a -> t b) -- Monad
cobind :: (t a -> b) -> (t a -> t b) -- Comonad
ap :: t (a -> b) -> (t a -> t b) -- Applicative
The resulting function type is the same in all these cases - the difference is the type of the input function. There are other similar functions which return a `(t a -> t b)` too.The "ordered computation" isn't unique to monads, it applies to all of these when you chain them. For monads particularly though, you can't begin the continuation until the previous result has been generated - whereas with a comonad, you can begin the continuation right away and extract the value afterwards (inside the continuation).
Can also think of it like a producer/consumer or push/pull thing. Monads push values into some type `t`, and comonads pull values out of `t`.
The naming of `return` is perhaps unfortunate as it gives the impression you're returning a value (done to make do-notation look like imperative code) - but monads don't return values. `return` produces a computation.
`coreturn` is usually called `extract`, which is better naming - it extracts a value from a computation.
The order of arguments is also unfortunate because it makes the above pattern less obvious - they're usually written as:
fmap :: f a -> (a -> b) -> f b
bind :: m a -> (a -> m b) -> m b
So it's not obvious that `fmap` is transforming a function `(a -> b)` into one `(f a -> f b)`, etc.