Next we derive the necessary instances. Note that we make use of the
feature to change record field names. In this case we drop the first 4
characters of every field name. We also modify constructor names by
lower-casing them:

A constructor will be encoded to an object with a field
tagFieldName which specifies the constructor tag (modified by
the constructorTagModifier). If the constructor is a record
the encoded record fields will be unpacked into this object. So
make sure that your record doesn't have a field with the same
label as the tagFieldName. Otherwise the tag gets overwritten
by the encoded value of that field! If the constructor is not a
record the encoded constructor contents will be stored under
the contentsFieldName field.

Constructor names won't be encoded. Instead only the contents of the
constructor will be encoded as if the type had a single constructor. JSON
encodings have to be disjoint for decoding to work properly.

When decoding, constructors are tried in the order of definition. If some
encodings overlap, the first one defined will succeed.

Note: Nullary constructors are encoded as strings (using
constructorTagModifier). Having a nullary constructor alongside a
single field constructor that encodes to a string leads to ambiguity.

Note: Only the last error is kept when decoding, so in the case of
malformed JSON, only an error for the last constructor will be reported.

A constructor will be encoded to a 2-element array where the
first element is the tag of the constructor (modified by the
constructorTagModifier) and the second element the encoded
contents of the constructor.

Generates a lambda expression which encodes the given data type or
data family instance constructor as a JSON string by using the given encoding
functions on occurrences of the last two type parameters.

Generates a lambda expression which parses the JSON encoding of the given
data type or data family instance constructor by using the given parsing
functions on occurrences of the last two type parameters.