Codes and interpretations
The class of representable datatypes.
The SOP approach to generic programming is based on viewing
datatypes as a representation (
Rep) built from the sum of
products of its components. The components of are datatype
are specified using the
Code type family.
The isomorphism between the original Haskell datatype and its
representation is witnessed by the methods of this class,
to. So for instances of this class, the following
laws should (in general) hold:
You typically don't define instances of this class by hand, but rather derive the class instance automatically.
Option 1: Derive via the built-in GHC-generics. For this, you
need to use the
DeriveGeneric extension to first derive an
instance of the
Generic class from module GHC.Generics.
With this, you can then give an empty instance for
the default definitions will just work. The pattern looks as
import qualified GHC.Generics as GHC import Generics.SOP ... data T = ... deriving (GHC.
Generic, ...) instance
GenericT -- empty instance
HasDatatypeInfoT -- empty, if you want/need metadata
Option 2: Derive via Template Haskell. For this, you need to
TemplateHaskell extension. You can then use
deriveGeneric from module Generics.SOP.TH
to have the instance generated for you. The pattern looks as
import Generics.SOP import Generics.SOP.TH ... data T = ...
deriveGeneric''T -- derives
Tradeoffs: Whether to use Option 1 or 2 is mainly a matter of personal taste. The version based on Template Haskell probably has less run-time overhead.
It is possible to give
Generic instances manually that deviate
from the standard scheme, as long as at least
The code of a datatype.
This is a list of lists of its components. The outer list contains one element per constructor. The inner list contains one element per constructor argument (field).
Example: The datatype
data Tree = Leaf Int | Node Tree Tree
is supposed to have the following code:
type instance Code (Tree a) = '[ '[ Int ] , '[ Tree, Tree ] ]
Converts from a value to its structural representation.
Converts from a structural representation back to the original value.
A class of datatypes that have associated metadata.
It is possible to use the sum-of-products approach to generic programming without metadata. If you need metadata in a function, an additional constraint on this class is in order.
You typically don't define instances of this class by hand, but
rather derive the class instance automatically. See the documentation
Generic for the options.