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

Add support for records as GVal #57

Open
flip111 opened this issue Aug 28, 2020 · 3 comments
Open

Add support for records as GVal #57

flip111 opened this issue Aug 28, 2020 · 3 comments

Comments

@flip111
Copy link

flip111 commented Aug 28, 2020

Would it be possible to add support for records that become GVal dictionaries? Maybe with GHC.Generics instances can automatically be derived. I would prefer to just put my records straight into the template instead of writing conversion functions from record to hashmap.

@tdammers
Copy link
Owner

In principle, yes, of course. Automatically doing it for any record type would be a bad idea though, because a 1:1 mapping is often not what you want - not all records represent straightforward dumb data, after all, and it would only work for record types where all fields have GVal instances themselves.

Another thing worth thinking about is how names should work out; it is not clear at all whether the record field names should become Ginger dictionary keys directly, or if some name mangling should be applied. Haskell record fields often have prefixes due to the lack of per-record namespacing in the language, but on the Ginger side, we might not want to retain those prefixes. Haskell record fields generally use camel case, but we might prefer a different casing convention on the Ginger side. Those are all choices we should leave to the consumer.

All that said, I'm not at all opposed to the idea; if you want to sink some work into making it happen, I'm sure we can come up with something worth merging. Generics is probably the way to go here, or Template Haskell if we have to. I would only provide the tools though, not any actual instances, as that would (see above) be a bit too disruptive for my taste.

@flip111
Copy link
Author

flip111 commented Aug 29, 2020

I'm not so good yet with GHC.Generics .. this is as far as i get and it doesn't work

class GenericGVal rep where
  genericToGVal :: forall a. [(T.Text, a)]

instance GenericGVal f => GenericGVal (M1 D x f) where
  genericToGVal = genericToGVal @f

instance GenericGVal f => GenericGVal (M1 C x f) where
  genericToGVal = genericToGVal @f

instance Selector s => GenericGVal (M1 S s (K1 R t) f) where
  genericToGVal = [(T.pack $ selName (undefined :: M1 S s (K1 R t) ()), ????? )]

instance (GenericGVal a, GenericGVal b) => GenericGVal (a :*: b) where
  genericToGVal = genericToGVal @a <> genericToGVal @b

instance GenericGVal U1 where
  genericToGVal = []

I think all your objections:

  • customize mapping
  • naming of keys
  • casing

Are the same problems that are being faced when mapping JSON to records. Aeson has a great solution for this where you can automatically derive the common case and implement the typeclass yourself (with some helpers) for the customizing. Take a look at this package for example https://hackage.haskell.org/package/aeson-casing

@tdammers
Copy link
Owner

tdammers commented Aug 29, 2020 via email

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