That sounds nice in theory, but real programs have multiple channels of IO going on: std IO, logging, network, database, file system. I follow discussions in Haskel groups sometimes, and combining and untangling multiple monads is a persistent problem that doesn't have a good solution yet.
You should try actually doing some Haskell programming. There are some anti-patterns but the RIO pattern is very coherent and flexible. One IO base monad, one readerT that holds an IORef that gives you access to every other effect you need.
The IO monad is for reifying execution order of a program. You more or less never have multiple IO monads.
> combining and untangling multiple monads
What? I have to assume you mean combining and untangling multiple effects in an effect system. And the solution is simple: don't. IO is the only monad you use for all IO: logging, networking, databases, and filesystems included. Adding a layer of ReaderT on top is about the most complicated you do. Every other monad is pure. Effect systems are a great way to build abstractions that aren't usually worthwhile. It is the same kind of mentality that leads to AbstractWumbleProviderFactoryBean-oriented programming in Java.
It's debatable how much one is willing to describe historical solutions like MTL style to be a "good" solution to this problem (I explained the downsides in my talk "A History of Effect Systems"[1] at Zurihac 2025), but I certainly have no hesitation in describing my capability-based effect system Bluefin[2], as a good solution.
For the channels you describe above the type signature would look like this
Six different capabilities that give you access to six different channels of IO. A "Yield" to which you yield strings to stdout, an "Await" from which you can await strings from stdin, a "Yield" to which you yield log messages, and three abstract effects that allow you to do network, database and file system operations (abstract because I'm not sure exactly how you want them defined, but there's an example of the implementation of a file system effect at https://hackage-content.haskell.org/package/bluefin-0.6.0.0/...).No problem with combining or untangling monads whatsoever. This is the natural conclusion of galaxyLogic's point: instead of dividing your program into two parts (IO and not IO) you divide it into six parts (or maybe 2^6 parts?) according to which fine grained effects you have in scope.
If you (or anyone) has any questions about Bluefin I'm happy to help. Please feel free to ask here or on the issue tracker[3].
[1] https://www.youtube.com/watch?v=RsTuy1jXQ6Y
[2] https://hackage.haskell.org/package/bluefin
[3] https://github.com/tomjaguarpaw/bluefin/issues/new