|Version 18 (modified by 6 years ago) (diff),|
The new Generic Deriving mechanism (ongoing work)
GHC includes a new (in 2010) mechanism to let you write generic functions. It is described in A generic deriving mechanism for Haskell, by Magalhães, Dijkstra, Jeuring and Löh. This page sketches the specifics of the implementation; we assume you have read the paper.
This mechanism replaces the previous generic classes implementation. The code is in a branch of GHC; you can get it with
darcs get http://darcs.haskell.org/ghc-generic-15Feb11/ghc.
Changes from the paper
In the paper we describe the implementation in UHC. The implementation in GHC is slightly different:
- We are using type families, so the Representable0 and Representable1 type classes have only one type argument. So, in GHC the classes look like what we describe in "Avoiding extensions" part of Section 2.3 of the paper. This change affects only a generic function writer, and not a generic function user.
- Default definitions (Section 3.3) work differently. In GHC we don't use a
DERIVABLEpragma; instead, a type class can declare a generic default method, which is akin to a standard default method, but includes a generic type signature. For example, the
Encodeclass of Section 3.1 is now:
class Encode a where encode :: a -> [Bit] generic encode :: (Representable0 a, Encode1 (Rep a)) => a -> [Bit] encode = encode1 . from0This removes the need for a separate default definition and a pragma.
- To derive generic functionality to a user type, the user no longer uses
(Section 4.6.1). Instead, the user gives an instance without defining the method; GHC then uses the generic default. For instance:
instance Encode [a] -- works if there is an instance Representable0 [a]
InstInfofor each data type that fulfills the
Representable0instance for that type, allowing it to be handled generically (by kind-
- The representation types and core functionality of the library live on
- Many names have been added as known in
- Most of the code generation is handled by
What already works
Representable0instances are automatically generated when
- Remove all of the old deriving mechanism stuff
- Properly deal with isTuple information for constructors
- What about base types like
- For temporary testing, a file test/Main.hs is available with sample datatypes.
- Currently, in
TcDeriv.genGenericRepBindwe generate instances using
mkLocalInstance. Is this right, or should we use
mkImportedInstanceinstead? SLPJ: mkLocalInstance: it's as if the instance declaration was in this module, right?