generics-sop
generics-sop copied to clipboard
1. Implement `SOP.Generic (GHC.Generically a)` and 2. export SOP.Generically
Here are 2 suggestions once we get GHC.Generically and GHC.Generically1 in base 4.17.
Those are simply newtypes, if you have a definition in terms of GHC.Generic or GHC.Generic1 then you give it an instance.
-- GHC.Generics
newtype Generically a = Generically a
newtype Generically1 f a = Generically1 (f a)
-
SOP.Generichas an implementation in terms ofGHC.Generic, thus I propose the following instance:instance (GHC.Generic a, GFrom a, GTo a, Rep a ~ SOP I (GCode a)) => SOP.Generic (GHC.Generically a) where type Code (GHC.Generically a) = GCode a from = gfrom to = gtoThis way an instance of
SOP.Generic Tcan be derived:deriving SOP.Generic via GHC.Generically T. -
I also propose defining a newtype with the same name as
Generically, to be imported qualified withSOP.Generically, it will serve the same purpose but forSOP.Genericdefinitions. I think every data-type generic library should export a name like that. If I can implementBinaryin terms ofSOP.GenericI defineinstance (SOP.Generic a, ..) => Binary (SOP.Generically a):-- Generics.SOP newtype Generically a = Generically a
A newtype like SOP.Generically can be combined with a library like generic-override that overrides the generic representation of an instance, so we decouple a generic implementation from modifying the generic implementation:
data X = X { s :: Int, p :: Int }
deriving stock GHC.Generic
-- 1.
deriving SOP.Generic via GHC.Generically X
-- 2.
deriving (Semigroup, Monoid) via SOP.Generically
(Override X
'[ "x" `As` Sum Int
, "y" `As` Product Int
])
Thanks! In principle, I'm in support of both, although regarding part 2, I'm somewhat afraid that the presence of the type will go mostly unnoticed, because the library itself has hardly any generic functions, so it would basically be a type without instances.
For 1. I think this pragma should work
#if MIN_VERSION_base(4,17,0)
#define HAS_GENERICALLY
#endif
And then this is a backwards compatible definition for GHC.Generically
#ifdef HAS_GENERICALLY
instance .. => SOP.Generic (GHC.Generically a) where
..
#endif
For 2. I share the concern, I was thinking that it would mostly be up to other libraries that depend on generics-sop to specify instances without having to depend on another library. generics-sop can add instances for the base classes with time.
Maybe it belongs in basic-sop instead? It already has a generics-sop Eq instance, but there I feel like it would go unnoticed as well.
For 1. you can use the generically compatibility package.
I think Generically¹ should be defined so people can start attaching instances to it, I would expect that if I have the generics-sop package that I can define generic instances. It just depends if you mind defining orphan instances in basic-sop.
¹ What name should be chosen? SOPGenerically? At first I thought of qualified Generically: SOP.Generically but I don't like the idea of dealing with the clash.
import Generics.SOP hiding (Generically(..))
import qualified Generics.SOP as SOP (Generically)
There is already a name clash in Generic type-class name.
So you're fine with exporting this as Generically?
So you're fine with exporting this as Generically?
It's up to @kosmikus
Yes, as long as we don't rename the Generic class, I don't see an issue with calling the newtype Generically as well.
@Icelandjack do you want to submit a PR? Otherwise, I'll try to do this whenever I next get around to making changes on the library.
I made a PR #159 and updated some of the documentation. I didn't build the project so there may be some errors.