"X is just a monad" isn't a useful statement, because lots of types are monads (e.g. lists, hash maps, and nullable pointers).
An important difference between async/await and Haskell's `IO a` is that it's possible for asynchronous code to invoke sync code, and in some languages (such as Rust) vice-versa. So it acts more like a monad transformer, providing operations `IO a -> AsyncIO a` and `AsyncIO a -> IO a`.
The main challenge of async/await is that unskilled people who don't understand threads try to use async/await as a substitute, which leads to bizarre articles like "what color are your functions".
I said async functions can be treated as the IO monad. And I also said that I realize that promises are themselves monads but that wasn’t my point. The point was to use async functions as coloring in the same way Haskell does it with the IO monad.
An important difference between async/await and Haskell's `IO a` is that it's possible for asynchronous code to invoke sync code, and in some languages (such as Rust) vice-versa. So it acts more like a monad transformer, providing operations `IO a -> AsyncIO a` and `AsyncIO a -> IO a`.
The main challenge of async/await is that unskilled people who don't understand threads try to use async/await as a substitute, which leads to bizarre articles like "what color are your functions".