Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A way to get a Generic instance equivalent to that of plain haskell record? #148

Open
YPares opened this issue Jan 26, 2021 · 3 comments
Open

Comments

@YPares
Copy link

YPares commented Jan 26, 2021

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?

@YPares
Copy link
Author

YPares commented Jan 27, 2021

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

@acowley
Copy link
Contributor

acowley commented Jan 29, 2021

Interesting! Is there anything you'd like to see done in the vinyl package to support this?

@YPares
Copy link
Author

YPares commented Jan 29, 2021

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants