A way to get a Generic instance equivalent to that of plain haskell record?
Opened this issue · 3 comments
Currently, the Generic instance of Rec
is oblivious of the functor wrapping the fields. This means the Generic instance it provides cannot be equivalent to that of an equivalent Haskell record.
Would there be a way to have:
newtype RecWithGeneric rs = RecWithGeneric (Rec ElField rs)
type Person1 = RecWithGeneric '["firstname" ::: Text, "lastname" ::: Text]
data Person2 = Person2
{ firstname :: Text
, lastname :: Text }
that ensures the Generic instances for Person1 and Person2 can be used instead of one another?
Okay, I hacked something around and managed to do it. It's used in that example: https://github.com/YPares/selda/blob/work-branch/vinyl-example/app/Main.hs#L14
Interesting! Is there anything you'd like to see done in the vinyl
package to support this?
@acowley If you'd like, maybe you'd want to upstream my GenRec newtype into vinyl. But as such it's kinda limited. It only supports Rec
with the ElField
functor. (And ARec
, but simply through a brute-force conversion to Rec to reuse the instance for Rec, although it's possible GHC is smart enough to optimize away the whole conversion, I didn't check).
Maybe SRec
could be given an instance too.
Also, any functor should work, as long as you "insert" it in the Generic representation of each field. (I never really checked how Generics behave with HKDs à la barbies)
But the instance of Rep
I derive can work for basically any Generic-based library (it works with Aeson too for instance), as it only uses M1, (:*:) and K1. Maybe the same could be done for CoRec
, but given a lot of Generic-based libs don't like sum types or hack around them, it's less useful anyway IMHO.