Haskell has <$> and the infrastructure of HKTs to stop this infectious propagation of IO, other languages do not, and their async/await colors do not isolate side-effectful actions from the rest pure parts of your codebase.
> Which ones? I think there's always some way to isolate, even if ugly.
Almost all of them? You need referential transparency (via laziness) too, otherwise your attempt at isolation will break at the first binding expression in a local scope for future processing elsewhere:
...
let arg = processData <$> ioAction
in ...
Do you want to wrap-and-call-later all of these cases into lambdas by hand? :)
As some other comment said, it's like the Haskell IO monad and that's OK, because it lets you isolate and be aware of the implications of that code.