Skip to content

Add `Generically` (or `WrappedGeneric`) newtype to `GHC.Generics`

Proposal

In recent years, the DefaultSignatures extension has seen popular use as a mechanism for providing derived typeclass instances via GHC.Generics. Although undeniably useful, I have always felt it is somewhat ugly: it is mutually exclusive with other, non-Generic default method implementations, and it can only be used for one generic deriving mechanism, so implementations must choose between GHC.Generics and Data.Data.

Fortunately, with the advent of DerivingVia, there is a better way: simply attach generic instances to a separate newtype, defined like

newtype Generically a = Generically { unGenerically :: a }

instance Generic a => C (Generically a) where
  ...

then derive instances using DerivingVia as follows:

data Foo = Bar X | Baz Y Z
  deriving C via Generically Foo

The Generically name already exists for this purpose in the generic-data package, making it a good candidate name for a newtype in GHC.Generics (generic-data could simply re-export the type with suitably recent versions of base). An alternate name would be the more conventional WrappedGeneric. I don’t have much of a preference either way, but I do think the Generically name is cute, especially when used with DerivingVia.

Rationale

I believe this type should be in base because it is

  1. clearly generally useful in the same way that similar newtypes in base like WrappedMonad are (and probably even more so),

  2. extremely lightweight in terms of additional API complexity (it’s just a newtype),

  3. isn’t worth depending on a separate package for, encouraging a proliferation of (possibly name-conflicting) newtypes in individual packages if it isn’t in base, and

  4. is an opportunity to add instances based on Generic for classes already in base.

Overall, it’s something that would feel right at home in GHC.Generics to me.

As a final note, whichever name people prefer, it would of course make sense to provide an analogous Generically1 or WrappedGeneric1 type for Generic1 (as generic-data does as well).

See also: the discussion on libraries@haskell.org.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information