-
Notifications
You must be signed in to change notification settings - Fork 48
Description
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.Generic
has 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 = gto
This way an instance of
SOP.Generic T
can 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.Generic
definitions. I think every data-type generic library should export a name like that. If I can implementBinary
in terms ofSOP.Generic
I 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
])