BTW: Haskell uses its IO wrapper also only for a very narrow set of effects.
One of my favorite examples: `head []` will result in a crash at runtime. IO won't safe you. (Besides that the whole "effect wrapping" story in Haskell is anyway shallow at best. There is nothing like "none observable effects" at all as every computation needs to happen in space-time, leaving observable traces therein; you can't define away "side channels" and call the result "pure"; that's mocking reality).
Having a notion of co-effects (or however you please to call them) is imho actually much more important than talking about effects (as effects are in fact neither values nor types—something that all the IO kludges get wrong).
I think the first practicable approach in the mainstream about this topic will be what gets researched and developed for Scala. The main take away is that you need to look at things form the co-effects side first and foremost!
In case anybody is interested in what happens in Scala land in this regard:
Yep. I think it is needed to satisfy some category theory thing but I never got a good answer on that. I like to use nri-prelude since I went from Elm to Haskell and it has the same idioms, to wit `head : List a -> Maybe a`.