Re: Proposal: Add Eq1 and Ord1 instances in GHC.Generics, and synchronize with Data.Functor.* types

- GHC.Generics is missing Eq1, Ord1, Show1, Read1 instances
I'd be in favor of this idea. However, see my caveat below.
Data.Functor.* is missing Semigroup and Monoid instances (that my previous proposal would add to GHC.Generics)
This is (or was) by design. See [1] for the full story. We migrated the Data.Functor.* module hierarchy from transformers, which is a library that is very much committed to using a Haskell98 style of code. The style of Semigroup/Monoid instances you're proposing to be added would not be Haskell98, since an instance like this: instance Monoid (f (g p)) => Monoid (Compose f g p) Would not be Haskell98 due to its use of FlexibleContexts. Of course, there are other ways one could conceivably define Monoid instances for these classes that are Haskell98, but as Edward noted in [1], they each had subtle flaws. So, we punted on the idea of adding Semigroup/Monoid instances at the time. Now granted, we didn't adhere to this Haskell98 philosophy everywhere. We did add Data instances for Compose et al., for example, and those require FlexibleContexts due to the way they work. But Data is a GHC-specific class, so this exception is somewhat understandable. However, you're proposing we make an exception for Semigroup/Monoid. Is this OK? Granted, the Haskell Report mentions neither to my knowledge, but at the same time, nothing about them requires FlexibleContexts on the surface. So I'm a bit ambivalent about the idea. Now, back to Eq1, Ord1, Show1, and Read1. The arrival of these classes into base predates GHC.Generics, so when Eq, Ord, Read, and Show instances were added for the data types in GHC.Generics, they were of the form: instance (Eq (f (g p)) => Eq ((f :.: g) p) instance (Ord (f (g p)) => Ord ((f :.: g) p) ... Of course, this is not what is done for the data types in the Data.Functor.* hierarchy. For instance, there we have: instance (Eq1 f, Eq1 g) => Eq (Compose f g p) instance (Ord1 f, Ord1 g) => Ord (Compose f g p) ... So while we could add Eq1, Ord1, Read1, and Show1 instances for the data types in GHC.Generics, it does serve as a reminder that the corresponding Eq, Ord, Read, and Show instances are inconsistent with the ones from the Data.Functor.* space. Personally, I don't think this need be a dealbreaker—after all, Eq1 et al. simply weren't around at the time. It just means that if we ever have a (theoretical) merger of the data types between Data.Functor.* and GHC.Generics, we'd have to pick one style of Eq/Ord/Read/Show instances over the other. But this is a bridge we need not cross now. *tl;dr* I'm +1 in favor of your first idea, and ambivalent about your second idea. Ryan S. ----- [1] https://ghc.haskell.org/trac/ghc/ticket/11135#comment:25
participants (1)
-
Ryan Scott