Is there any particular reason IO functions in the standard libraries aren't grouped into type-classes?

This might allow for:

1) Testing IO code without actual input and output. (I have done this on a small scale, but it presently involves much ugliness).
2) Redirecting output of a function that neglects to take a handle without a bunch of calls to dup.
3) Forwarding IO over a connection to a remote system, allowing code written to work locally to be applied remotely, or vice-versa.
4) Wrapping dangerous IO actions in additional sanity checks.

Thoughts?