Open flip111 opened 4 years ago
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.
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:
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
Yep, aeson is pretty much what I had in mind. I'll take a closer look when I can make the time.
On Sat, Aug 29, 2020, 23:37 flip111 notifications@github.com wrote:
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
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tdammers/ginger/issues/57#issuecomment-683344581, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAK6HR5ZTHFCSRI6TQVWHB3SDFYINANCNFSM4QOLNHJA .
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.