Difference between revisions of "Orphan instance"

From HaskellWiki
Jump to navigation Jump to search
(Newtype wrapper workaround)
 
Line 1: Line 1:
  +
== Description ==
  +
 
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.
 
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.
   
Line 7: Line 9:
 
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.
 
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 ==
  +
  +
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==
 
==When Orphan Instances can be useful==

Latest revision as of 10:13, 31 May 2015

Description

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

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

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