> Basically this is (in my mind) what's wrong with Haskell: it's overly concerned with the Platonic ideal.

I read this and I think what's got you rustled here is that Monad is such a generic concept. It's quite higher level and so you can do novel things like write functions that don't know how they're executing, just that they are.

As an example:

-- Config is a typeclass that enables getting a
-- keyval from a config. The return type is MonadIO
-- because config might need IO.
loadTarget :: (MonadIO m, Config a) => a -> m a
loadTarget config = do
v <- grabKeyVal "host" config
w <- grabKeyVal "port" config
return (v,w)

What does that code do? The answer (if it's written carefully) is that it depends on what the underlying monad is! And that's a good thing, in many cases. If the monad is Maybe + IO, then you have a conditional loader.

But if the monad is an array and IO then you can specify many hosts and many ports and this code enumerates them all. If that's passed to a ping function like so:

loadTarget config >>= pingHostPort

-- alternatively

doPings config = do
hostPort <- loadTarget config
pingHostPort hostPort

Well then your code will do the right thing, but a different thing, based entirely on the types alone! And you can generalize this out to even more powerful types. For example, you could write a web app that server side could do local network ports for you (why? you're a maliclious hacker of course!). In that case it might make sense to use the Continuation monad.

tl;dr and finally:

You say this is stupid abstract stuff, but the folks delivering features to you in the Javascript world disagree. You have generators now, which are a much more real and fair explanation of how to model monads in Javascript than that silly code snippet you posted that doesn't capture the spirit of them at all.

What's more, careful application of these concepts leads to libraries which are just better than anything you can have without appealing to generators. A great example of this Purescript-config. Here is an actual (redacted) same of some code I use at work in an AWS Lambda function to read the environment:

https://gist.github.com/KirinDave/9af0fc90d005164743198692f3...

So I have complete error reporting (full sets of missing keys) just by describing how to fetch the values from the environment. I can transparently switch to any other file type under the covers by changing from using "fromEnv". I only know that there is a key-value store in there.

Doing this in OO is really, really hard to get right, because imperative OO code cannot easily parameterize the execution strategy hierarchically without appealing to generics and ad-hoc polymorphism. That's hard.

The applicative style adopted here is very simple to re-interpret, because we can parameterize code on monads and applicatives (which explain the execution strategy of this code beyond its coarse structure) as we see fit.

You can do that with generators but it's frustratingly hard. Doing it in a truly generic way? Even harder. For this approach, the results are free (and Free, but hey).

I can give you other examples of how Purescript makes certain difficult aspects of javascript simply vanish, if you'd like.