
From what I understand, the current best practices are to build your package dependencies like so:
Parsec MyMonadT MyMonadT_Parsec -- orphan instances go here ProjectPackage
This does mean splitting up your project into three packages, but decouples the orphan instance into its own package where it can do the least damage :)
Lets assume the above are modules rather than packages (same difference, but fewer indirections in the explanation to follow): if ProjectPackage imports MyMonadT_Parsec and is itself meant to be imported by other modules, then that decoupling breaks down (unless MyMonadT is a private class, in which case there is only one provider of instances, who can try to manage the situation).
At the very least it should go into its own module which can be imported only in the places that need it, similar to Control.Monad.Instances defining the orphan instance for Monad ((->) r).
Orphan instances aren't themselves bad, I think. But since current technology doesn't allow for import/export control, they always indicate a problem, hence the warning. When possible, the problem should be avoided, by making either the class or the type private (if neccessary by wrapping a common type in a newtype). That doesn't mean that the problem can always be avoided, just that there is something that needs attention. Back to that import hierarchy:
Parsec MyMonadT MyMonadT_Parsec -- orphan instances go here ProjectPackage
If ProjectPackage is meant to be imported, there are at least two ways to proceed. Version A is to split the dependent modules, so that each of them can be used with or without the import. Parsec MyMonadT MyMonadT_Parsec -- orphan instances go here ProjectPackageWith -- imports, and implicitly exports, MyMonadT_Parsec ProjectPackageWithout -- no import, no implicit export So clients can still use ProjectPackageWithout if they get the instances by another route. This only works for convenience instances where the instances are nice to provide for clients, but not needed in ProjectPackage itself - in essence: ProjectPackageWith(module ProjectPackageWithout) where import MyMonadT_Parsec import ProjectPackageWithout If ProjectPackage actually depends on the existence of those orphan instances, plan B is to delay instance resolution, from library to clients, so instead of importing the orphan instances module ProjectPackage where import MyMonadT_Parsec f .. = .. orphan instances are available, use them .. (which leads to the dreaded implicit export), you'd just assert their existence: module ProjectPackage where f :: .. Orphan x => .. ; f .. = .. use orphan instances .. so the client module would have to import both ProjectPackage and MyMonadT_Parsec if it wants to call 'f', or find another way to provide those instance. Of course, the same concerns apply to the client modules, so you end up delaying all instance resolution until the last possible moment (at which point all the orphans need to be imported). If there is a main module somewhere (something that isn't itself imported), that is the place where importing the orphan instances won't cause any trouble (other than that all the users of such instances better have compatible ideas about what kind of instance they want, because they all get the same ones). If there is no main module (you're writing a library meant to be imported), you better delay the import of any orphans or provide both libraryWith and libraryWithout. It isn't pretty. Claus