Type-level generics

Ryan Scott ryan.gl.scott at gmail.com
Sat Sep 2 15:35:58 UTC 2017

Several good points were brought up. Let me go through them and try to
make sense of what I can:

> When I looked at it the last time, there were some apparent leftovers in the form of types or type parameters never used.

Are you referring to the `p` type parameters that are found in most of
the data types in GHC.Generics? If so, they are most definitely
used—try deriving Generic1 to see this in action! It's true that in
the context of Generic (without the 1 at the end) the `p` isn't used,
but this is by design, as this allows us to share the same
representation types across Generic and Generic1.

> there is no possibility to work with types with more than one parameter.

Quite true. But I posit that engineering GHC.Generics to work with
more than one type parameter at a time is much harder than it sounds.
After all, to profitably work with even a *single* type parameter
(what Generic1 does), we must bring in three additional representation
types: Par1, Rec1, and (:.:), depending on where in the datatype the
last type parameter occurs. If we wanted to have, say, Generic2, we'd
similarly need to be able to work with many more combinations of type
parameter positions, such as:

* data Foo1 a b = Foo1 a b
* data Foo2 a b = Foo2 (Either a b)
* data Foo3 a b = Foo3 (Either b a)
* etc.

A naïve approach would be to tack on another type parameter at the end
of every representation type, and introduce more types to deal with
all the combinations of the first and second type parameter that could
arise. But this approach doesn't scale well—after all, at what number
N do you stop introducing new representation types? So extending
GHC.Generics to deal with more than one type parameter is far from
obvious to me (let alone whether it could be made backwards compatible
with the current API).

> the GHC.Generics module looks a bit unpolished and ad-hoc at the moment.

Yes, quite literally everything in GHC.Generics is one large, ad hoc
hack. But it's also a darn useful one :)

> It looks like there's still one confusing reference to Par0: "Note how Par0 and Rec0 both being mapped to K1 allows us to define a uniform instance here. " but at least it's not tangled up in the already very confusing examples and signatures.  I think that sentence can be deleted entirely now?

Indeed, an earlier part of the documentation in that module mentions
that Par0 was deprecated (and removed, in fact), so we really
shouldn't be mentioning it elsewhere. I'll remove that sentence.

Ryan S.

More information about the ghc-devs mailing list