Split up Data.Generic and move generic implementations to type classes

Now the generic functions are all as part of the type classes themselves,
which is much more cohesive.