# Difference between revisions of "Orphan instance"

(instance Monad Either) |
(link to Monad Transformer Library) |
||

Line 15: | Line 15: | ||

The <hask>Monad</hask> instance of <hask>Either</hask> is a good example. |
The <hask>Monad</hask> instance of <hask>Either</hask> is a good example. |
||

It is not defined where <hask>Either</hask> is defined, thus all of its <hask>Monad</hask> instances must be orphan. |
It is not defined where <hask>Either</hask> is defined, thus all of its <hask>Monad</hask> instances must be orphan. |
||

− | Instead it is defined both in <hask>Control.Monad.Error</hask> of the Monad Transformer Library |
+ | Instead it is defined both in <hask>Control.Monad.Error</hask> of the [[Monad Transformer Library]] |

and in <hask>Control.Monad.Trans.Error</hask> of its leightweight cousin the 'transformers' package. |
and in <hask>Control.Monad.Trans.Error</hask> of its leightweight cousin the 'transformers' package. |
||

Since some packages use MTL and others 'transformers' it becomes difficult to use that instance at all, |
Since some packages use MTL and others 'transformers' it becomes difficult to use that instance at all, |

## Revision as of 22:54, 7 February 2009

## Question

What is an Orphan instance and why is it bad?

## Answer

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 can not be excluded explicitly. All instances defined in a module A are imported automatically when importing A. This applies recursively to all modules imported by A.

Say you want to make use of a type class instance in your module, then you must import both the class and the type directly, or you must import modules which itself import at some point the class and at some other point the type. If there is a non-orphan instance, you automatically get the instance imported. This way the compiler can restrict the set of modules to look for an instance if you want to apply it. So the problem is partially an efficiency problem, but this is not all.

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 somewhen. It is almost impossible to assert that, or put differently, it would reduce the composability of libraries considerably.

The `Monad`

instance of `Either`

is a good example.
It is not defined where `Either`

is defined, thus all of its `Monad`

instances must be orphan.
Instead it is defined both in `Control.Monad.Error`

of the Monad Transformer Library
and in `Control.Monad.Trans.Error`

of its leightweight cousin the 'transformers' package.
Since some packages use MTL and others 'transformers' it becomes difficult to use that instance at all,
although both instances are equivalent!
Practical advice:
It is questionable whether it is good style to use `Either`

to flag exceptional return values
and define an according `Monad`

instance for that purpose.
The explicit-exception package with its `Exceptional`

might be a better choice.

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.

A last advice:
If you encounter a missing instance for a class or a type of a package,
resist to define your own orphan instance, because it will likely collide with such instances of other packages,
or it will collide with new instances added in later versions of that package.
Instead ask the package author to add your instance.
Sometimes it turns out that the instance was not included for the good reason,
that there is more than one reasonable instance definition.
If your instance cannot be included, follow the advices in the article about multiple instances.

## See also

- Multiple instances
- Libraries mailing list on Orphan instances can be good
- Partial Revelation feature of Modula-3 which causes similar problems like Haskell's type class instances