So do you need monads in Haskell because that's the only way you could do some of the things that are trivial in an imperative language (albeit verbose and arguably inelegant)?
Not exactly. For example, IO actually existed in Haskell before the IO Monad. It essentially used lists injected and retuned from the main function, plus the fact that Haskell is lazily evaluated (so those IO commands in the list wouldn’t be evaluated until main is run): https://stackoverflow.com/questions/17002119/haskell-pre-mon...
Haskell only "needs" monads for IO (there are other alternatives to implement io in a pure language too though). The reason that they are popular in haskell is that they are convenient and the reason that they are not popular in ML is that it lacks higher order types and things like typeclasses.