Orphan instance
Description[edit]
An orphan instance is a type class instance for class C and type T which is neither defined in the module where C is defined nor in the module where T is defined.
Type class instances are special in that they don't have a name and cannot be imported explicitly. This also means that they cannot be excluded explicitly. All instances defined in a module A are imported automatically when importing A, or importing any module that imports A, directly or indirectly.
Say you want to define an alternative instance to an existing instance. This is a bad thing, since if two instances for the same class/type pair are in scope, then you cannot describe in Haskell 98 which instance to use. If you want to use multiple instances for the same class/type, you have to ensure that they are never imported together in a module somewhere. It is almost impossible to assert that, or put differently, it would reduce the composability of libraries considerably.
Actually, non-orphan instances can avoid definition of multiple instances. For defining an instance you have to import the class and the type and then you will automatically have the according non-orphan instances imported, too. If you want to define a new instance then the compiler will reject it immediately.
Common workaround[edit]
Let's say you want an instance for Monoid Int that handles addition. Later on, you'd like to reuse that code for handling multiplication. But now, there's two definitions of Monoid Int!
A common workaround is to wrap your type in a newtype and create an instance for that newtype. Then, marshal (=convert) between the original type and the newtype where necessary. In our example, we would have two newtypes: one for addition and one for multiplication. We would then create Monoid instances for each newtype wrapper.
When Orphan Instances can be useful[edit]
It is worth noting that Orphan Instances can be viewed as a mechanism for writing modules of code with a fixed typed interface, but parameterized over the choice of implementation. In this case, Orphan Instances act as a sort of plugin architecture for providing alternative implementations with a uniform interface.
A basic treatment of the relationship between type classes and modules (in the SML sense of modules) can be found at http://www.mpi-sws.org/~dreyer/papers/mtc/main-short.pdf and http://www.cse.unsw.edu.au/~chak/papers/modules-classes.pdf
See also[edit]
- Multiple instances
- Libraries mailing list on Orphan instances can be good
- Ideas on possible compiler warnings for coping with orphan instances
- Libraries mailing list on Relaxin the PVP with regards to adding instances
- Partial Revelation feature of Modula-3 which causes similar problems like Haskell's type class instances