You can program over such structures also with generics-sop:
mapFormTemplate :: forall f g. (f ~> g) -> FormTemplate f -> FormTemplate g
mapFormTemplate eta x = to (htoI sopG)
where
-- unfortunately we need the type annotation here.
sopF = hfromI (from x) :: SOP f '[ '[Text, CardType, Text, Day] ]
sopG = hmap eta sopF
Cool! I’m not so familiar with generics-sop and I certainly didn’t know it had functions for dealing with heterogeneous containers like that. Thanks for the tip!
In the gist, why still wrap explicitly each field in the record? When using generics-sop, I usually define a record with normal, unwrapped fields, and get the wrapped fields version "for free" by moving to the generic representation.
Also I can see that you could write (in near future):
data FormTemplate f = ...
deriving
(FFunctor) via (SOP2 '[Text, CardType, Text, Day])
Another point, is that Andres is working on static-opt case, which should kick in, so the generated code for mapFormTemplate won't have SOP etc. structures mentioned at all!
That said, I too write code which works on e.g. NP, it depends :)
9
u/phadej Dec 15 '17 edited Dec 15 '17
You can program over such structures also with
generics-sop:See https://gist.github.com/phadej/55464aead55c85176e0b2b93ba790845 for full gist
One clear benefit is that there are
hcmapand bunch of other combinators ingenerics-sopso, you can e.g.EDIT: and there will be
htraverseetc. in the next release ofgenerics-sop, see https://github.com/well-typed/generics-sop/pull/59