Improve the IO monad? Maybe separate it into smaller parts or, if the necessary discoveries happen in time, use some sort of declarative IO system.

Unambiguous semantics, when possible. When there is more than one possible instance of a type class for one data type, use newtype wrappers for all of those instances (no instance for the unwrapped version).