
Simon Marlow
kahl@cas.mcmaster.ca wrote:
Simon Marlow
wrote: We must have the property that the imports of a module do not affect its API - and the only way to have this property is to avoid orphan instances in library APIs.
To be more precise, I would say that each orphan instance in a library API must be the only export of a dedicated visible module, and only exported by that module.
(The only importers of orphan instances are typically Main modules, or ``almost-Main'' modules.)
Why do you believe that?
Sorry, I was being idealistic. ;-) I mean: The only importers of orphan instances should typically be Main modules, or ``almost-Main'' modules. That does of course require conscious effort... And it also assumes that orphan instances are in dedicated modules, so they are imported only intentionally. (I would propose to never warn about orphan instances in modules that export only a single orphan instance.)
We seem to have evidence to the contrary, with Control.Monad.Instances being imported by library modules.
That's because at least some of its instances are not ``truly orphan'', but should, and reasonably can, be in scope whenever both type and class are in scope. (Yes, for Functor ((->) a) this means that Haskell98 is wrong.) A counterexample to that is a Read instance that pulls in a major dependency, for example Parsec --- that should not be automatically in scope wherever both type and class are in scope, but only where it is actually needed. Haskell software architecture can be quite tricky... Wolfram