Personal tools

Orphan instance

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
m
(hints for avoiding orphan instances)
(One intermediate revision by one user not shown)
Line 25: Line 25:
 
that there is more than one reasonable instance definition.
 
that there is more than one reasonable instance definition.
 
If your instance cannot be included, follow the advices in the article about [[multiple instances]].
 
If your instance cannot be included, follow the advices in the article about [[multiple instances]].
  +
  +
  +
== Avoiding orphan instances ==
  +
  +
If you encounter an
  +
<haskell>
  +
instance C T
  +
</haskell>
  +
which is orphan, then you can try to
  +
  +
* move the instance declaration to the module defining class <hask>C</hask>,
  +
* move the instance declaration to the module defining type <hask>T</hask>,
  +
* wrap the type <hask>T</hask> in a custom type, like so
  +
<haskell>
  +
newtype N = N T
  +
instance C N
  +
</haskell>
  +
* define a custom class (unlikely to be useful), like so
  +
<haskell>
  +
class C => S
  +
instance S T
  +
instance S X -- for all X where an instance C X already exist
  +
</haskell>
  +
* not use the class <hask>C</hask> at all.
   
   
Line 31: Line 55:
 
* [[Multiple instances]]
 
* [[Multiple instances]]
 
* Libraries mailing list on [http://www.haskell.org/pipermail/libraries/2008-August/010399.html Orphan instances can be good]
 
* Libraries mailing list on [http://www.haskell.org/pipermail/libraries/2008-August/010399.html Orphan instances can be good]
  +
* [http://www.haskell.org/pipermail/haskell-cafe/2011-July/094014.html Ideas] on possible compiler warnings for coping with orphan instances
  +
* Libraries mailing list on [http://www.haskell.org/pipermail/libraries/2012-September/018398.html Relaxin the PVP with regards to adding instances]
 
* [http://modula3.elegosoft.com/pm3/pkg/modula3/src/discussion/partialRev.html Partial Revelation feature] of Modula-3 which causes similar problems like Haskell's type class instances
 
* [http://modula3.elegosoft.com/pm3/pkg/modula3/src/discussion/partialRev.html Partial Revelation feature] of Modula-3 which causes similar problems like Haskell's type class instances
   

Revision as of 22:43, 15 November 2012

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 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 lightweight 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:

The explicit-exception package with its
Exceptional
might be a better choice to use since it avoids the current problem with orphan Monad instances of
Either
.

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.


1 Avoiding orphan instances

If you encounter an

instance C T

which is orphan, then you can try to

  • move the instance declaration to the module defining class
    C
    ,
  • move the instance declaration to the module defining type
    T
    ,
  • wrap the type
    T
    in a custom type, like so
newtype N = N T
instance C N
  • define a custom class (unlikely to be useful), like so
class C => S
instance S T
instance S X  -- for all X where an instance C X already exist
  • not use the class
    C
    at all.


2 See also