You don't get any information from `IO _` functions, but that's the case with
every mainstream language, where you have an implicit `IO` on every single function.
The benefit is not in `IO` -- its that its absence on a function tells you that it is heavily restricted in what it can do.
If you want to go the other way, you can concretely model the kinds of effects you need parts of your programs to do, and use that model instead of `IO`. Even if you end up implementing it using `IO`, you know it can't use more than what your model exposes.
Both of these possibilities, while not truly unique (see Agda, etc.), are absolutely rare-to-nonexistent in mainstream languages. Effect modeling is a real shift in perspective.