Datatype-generic functions are based on the idea of converting values of
a datatype T into corresponding values of a (nearly) isomorphic type Rep T.
The type Rep T is
built from a limited set of type constructors, all provided by this module. A
datatype-generic function is then an overloaded function with instances
for most of these type constructors, together with a wrapper that performs
the mapping between T and Rep T. By using this technique, we merely need
a few generic instances in order to implement functionality that works for any
representable type.

Representable types are collected in the Generic class, which defines the
associated type Rep as well as conversion functions from and to.
Typically, you will not define Generic instances by hand, but have the compiler
derive them for you.

The Tree datatype has two constructors. The representation of individual constructors
is combined using the binary type constructor :+:.

The first constructor consists of a single field, which is the parameter a. This is
represented as Rec0 a.

The second constructor consists of two fields. Each is a recursive field of type Tree a,
represented as Rec0 (Tree a). Representations of individual fields are combined using
the binary type constructor :*:.

Now let us explain the additional tags being used in the complete representation:

The S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness
'DecidedLazy) tag indicates several things. The 'Nothing indicates
that there is no record field selector associated with this field of
the constructor (if there were, it would have been marked 'Just
"recordName" instead). The other types contain meta-information on
the field's strictness:

There is no {-# UNPACK #-} or {-# NOUNPACK #-} annotation
in the source, so it is tagged with 'NoSourceUnpackedness.

There is no strictness (!) or laziness (~) annotation in the
source, so it is tagged with 'NoSourceStrictness.

The compiler infers that the field is lazy, so it is tagged with
'DecidedLazy. Bear in mind that what the compiler decides may be
quite different from what is written in the source. See
DecidedStrictness for a more detailed explanation.

The 'MetaSel type is also an instance of the type class Selector,
which can be used to obtain information about the field at the value
level.

The C1 ('MetaCons "Leaf" 'PrefixI 'False) and
C1 ('MetaCons "Node" 'PrefixI 'False) invocations indicate that the enclosed part is
the representation of the first and second constructor of datatype Tree, respectively.
Here, the meta-information regarding constructor names, fixity and whether
it has named fields or not is encoded at the type level. The 'MetaCons
type is also an instance of the type class Constructor. This type class can be used
to obtain information about the constructor at the value level.

The D1 ('MetaData "Tree" "Main" "package-name" 'False) tag
indicates that the enclosed part is the representation of the
datatype Tree. Again, the meta-information is encoded at the type level.
The 'MetaData type is an instance of class Datatype, which
can be used to obtain the name of a datatype, the module it has been
defined in, the package it is located under, and whether it has been
defined using data or newtype at the value level.

There are many datatype-generic functions that do not distinguish between positions that
are parameters or positions that are recursive calls. There are also many datatype-generic
functions that do not care about the names of datatypes and constructors at all. To keep
the number of cases to consider in generic functions in such a situation to a minimum,
it turns out that many of the type constructors introduced above are actually synonyms,
defining them to be variants of a smaller set of constructors.

As :+: and :*: are just binary operators, one might ask what happens if the
datatype has more than two constructors, or a constructor with more than two
fields. The answer is simple: the operators are used several times, to combine
all the constructors and fields as needed. However, users /should not rely on
a specific nesting strategy/ for :+: and :*: being used. The compiler is
free to choose any nesting it prefers. (In practice, the current implementation
tries to produce a more-or-less balanced nesting, so that the traversal of
the structure of the datatype from the root to a particular component can be
performed in logarithmic rather than linear time.)

For part 1, we define a class Encode'. Perhaps surprisingly, this class is parameterized
over a type constructor f of kind * -> *. This is a technicality: all the representation
type constructors operate with kind * -> * as base kind. But the type argument is never
being used. This may be changed at some point in the future. The class has a single method,
and we use the type we want our final function to have, but we replace the occurrences of
the generic type argument a with f p (where the p is any argument; it will not be used).

class Encode' f where
encode' :: f p -> [Bool]

With the goal in mind to make encode work on Tree and other datatypes, we now define
instances for the representation type constructors V1, U1, :+:, :*:, K1, and M1.

So, U1 is just the unit type, :+: is just a binary choice like Either,
:*: is a binary pair like the pair constructor (,), and K1 is a value
of a specific type c, and M1 wraps a value of the generic type argument,
which in the lifted world is an f p (where we do not care about p).

There are no values of type V1 p to pass (except undefined), so this is
actually impossible. One can ask why it is useful to define an instance for
V1 at all in this case? Well, an empty type can be used as an argument to
a non-empty type, and you might still want to encode the resulting type.
As a somewhat contrived example, consider [Empty], which is not an empty
type, but contains just the empty list. The V1 instance ensures that we
can call the generic function on such types.

There is exactly one value of type U1, so encoding it requires no
knowledge, and we can use zero bits:

(Note that this encoding strategy may not be reliable across different
versions of GHC. Recall that the compiler is free to choose any nesting
of :+: it chooses, so if GHC chooses (a :+: b) :+: c, then the
encoding for a would be [False, False], b would be [False, True],
and c would be [True]. However, if GHC chooses a :+: (b :+: c),
then the encoding for a would be [False], b would be [True, False],
and c would be [True, True].)

In the case for :*:, we append the encodings of the two subcomponents:

The incoming x is converted using from, then we dispatch to the
generic instances using encode'. We use this as a default definition
for encode. We need the 'default encode' signature because ordinary
Haskell default methods must not introduce additional class constraints,
but our generic default does.

Datatype-generic functions as defined above work for a large class
of datatypes, including parameterized datatypes. (We have used Tree
as our example above, which is of kind * -> *.) However, the
Generic class ranges over types of kind *, and therefore, the
resulting generic functions (such as encode) must be parameterized
by a generic type argument of kind *.

What if we want to define generic classes that range over type
constructors (such as Functor, Traversable, or Foldable)?

Like Generic, there is a class Generic1 that defines a
representation Rep1 and conversion functions from1 and to1,
only that Generic1 ranges over types of kind * -> *. (More generally,
it can range over types of kind k -> *, for any kind k, if the
PolyKinds extension is enabled. More on this later.)
The Generic1 class is also derivable.

The representation Rep1 is ever so slightly different from Rep.
Let us look at Tree as an example again:

The representation reuses D1, C1, S1 (and thereby M1) as well
as :+: and :*: from Rep. (This reusability is the reason that we
carry around the dummy type argument for kind-*-types, but there are
already enough different names involved without duplicating each of
these.)

What's different is that we now use Par1 to refer to the parameter
(and that parameter, which used to be a), is not mentioned explicitly
by name anywhere; and we use Rec1 to refer to a recursive use of Tree a.

If one were to attempt to derive a Generic instance for a datatype with an
unlifted argument (for example, Int#), one might expect the occurrence of
the Int# argument to be marked with Rec0Int#. This won't work,
though, since Int# is of an unlifted kind, and Rec0 expects a type of
kind *.

One solution would be to represent an occurrence of Int# with 'Rec0 Int'
instead. With this approach, however, the programmer has no way of knowing
whether the Int is actually an Int# in disguise.

Instead of reusing Rec0, a separate data family URec is used to mark
occurrences of common unlifted types:

The strictness that GHC infers for a field during compilation. Whereas
there are nine different combinations of SourceUnpackedness and
SourceStrictness, the strictness that GHC decides will ultimately be one
of lazy, strict, or unpacked. What GHC decides is affected both by what the
user writes in the source code and by GHC flags. As an example, consider
this data type:

Datatype to represent metadata associated with a datatype (MetaData),
constructor (MetaCons), or field selector (MetaSel).

In MetaData n m p nt, n is the datatype's name, m is the module in
which the datatype is defined, p is the package in which the datatype
is defined, and nt is 'True if the datatype is a newtype.

In MetaCons n f s, n is the constructor's name, f is its fixity,
and s is 'True if the constructor contains record selectors.

In MetaSel mn su ss ds, if the field uses record syntax, then mn is
Just the record name. Otherwise, mn is Nothing. su and ss are
the field's unpackedness and strictness annotations, and ds is the
strictness that GHC infers for the field.