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

Alexis King lexi.lambda at gmail.com
Fri Aug 30 22:26:49 UTC 2019


I don’t think a derived `Generic` instance makes any more sense for `Generically` than a derived `Show` instance does. What would be the purpose of such an instance? Again, `instance C (Generically a)` is morally a function on dictionaries of type `Generic a -> C a`, and every instance on `Generically` should have that relationship. The existing `Generic` instance does, but a derived `Generic` instance would not.

If you want to leave that instance out, that’s fine with me; I highly doubt anyone would miss it. As I said before, it’s totally useless. But a derived `Generic` instance seems to have no purpose and would be inconsistent with the rules the other instances obey, so it seems strictly worse than no instance to me.

> On Aug 30, 2019, at 16:46, David Feuer <david.feuer at gmail.com> wrote:
> 
> I'm okay with moving those things into base. I'm even okay with doing some fancy ad hoc thing with Enum (Enum is a bad joke anyway). But the Generic instance gives me the heeby jeebies. Will it hurt anyone to just derive Generic there? (And both Generic and Generic1 for Generically1?). I'd rather not just omit it, but I think that would be better than this.
> 
> On Fri, Aug 30, 2019, 4:11 PM Alexis King <lexi.lambda at gmail.com <mailto:lexi.lambda at gmail.com>> wrote:
> > On Aug 30, 2019, at 14:33, David Feuer <david.feuer at gmail.com <mailto:david.feuer at gmail.com>> wrote:
> > 
> > I do have two concerns:
> > 
> > 1. The Genetically instances for base classes will need to move to base as well, including auxiliary classes where those are needed.
> 
> Agreed. For context, the existing instances of Generically (apart from the Generic instance, discussed below) are:
> 
> (Generic a, Eq (Rep a ())) => Eq (Generically a)
> (Generic a, Ord (Rep a ())) => Ord (Generically a)
> (Generic a, GBounded (Rep a)) => Bounded (Generically a)
> (Generic a, GEnum StandardEnum (Rep a)) => Enum (Generically a)
> (Generic a, GShow0 (Rep a)) => Show (Generically a)
> (Generic a, Semigroup (Rep a ())) => Semigroup (Generically a)
> (Semigroup a, Generic a, Monoid (Rep a ())) => Monoid (Generically a)
> 
> I think having these in `base` is actually a good thing, since it serves as a good set of examples of how to use GHC.Generics. The current `GEnum` class might be a little too much to include in `base`, but that’s fine: it can be specialized to `GEnum StandardEnum` without breaking backwards-compatibility with `generic-data` (which can continue to provide the more sophisticated implementation).
> 
> > 2. The Generic instance of Generically is currently a custom job. That's really not the greatest situation in general. Is that essential for some reason? If not, I think its Generic instance should just be derived.
> 
> This is an interesting point. Again for context, the current instance is as follows:
> 
> instance Generic a => Generic (Generically a) where
>   type Rep (Generically a) = Rep a
>   to = Generically . to
>   from = from . unGenerically
> 
> Which is to say `Generically` wrappers are invisible from the perspective of the `Generic` class.
> 
> Personally, I think this instance makes sense: think of every instance of some class `C` on `Generically a` is supposed to provide an instance of `C a` in terms of `Generic a`, and that is exactly what `Generic (Generically a)` does. However, it’s obviously a useless instance, since it’s just the identity function on an existing `Generic a` dictionary. In any case, I think it’s harmless, but I can understand why you might think it’s sketchy.
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20190830/44692d12/attachment.html>


More information about the Libraries mailing list