I have data which is a map. To make the question more concrete, let's think that it's represented as an assoc-list type D val = [(Key,val)]
(or as type D val = Map Key val
).
Key
is an "enum" type -- a sum of nullary constructors, e.g.:data Key = C1 | C2 | C3
There must be
instance ToJSON
forval
.
I'd like to implement
instance ToJSON val => ToJSON (D val)
which would be like instance Map String val
(producing an object with the corresponding key-value pairs) (an example, another example for HashMap
s), only more generic.
More generic means that I'm not restricted to String
or Text
as the key (such instances for Map
are found in the aeson package).
I want to learn how to use the generic mechanisms in aeson to do this concisely.
aeson already can convert "enums" to JSON strings, and also (C val1 val2 ...)
to objects with a single key (the constructor name, like this I assume: { "C":[val1,val2,...] }
) with genericToJSON defaultOptions{ sumEncoding = ObjectWithSingleField }
. And another conversion which uses the constructor names is with the default options for data types with non-nullary constructors: then the constructor name becomes the value of a "tag"
key. I could use similar code.
I think that even such an instance (for maps whose keys are from enums) would be useful addition to the library. But AFAIU neither aeson nor generic-aeson (which has adds some nicer conversion options) has such a conversion predefined.
aeson
package. The real problem I see here is convertingMap Key val
toMap Text val
, then outputting that. Why not just write a function that converts your keys to a type that already instancesToJSON
instead of worrying about generic programming? – bheklilrOptions
for both directions of conversion, having a singlefieldLabelModifier
for both direections, and I see how this can be done for an enum.) – imz -- Ivan ZakharyaschevToJSON
, that's not a problem for me. But that wouldn't automatically (or with some options) give me the desired JSON representation. Yes, with a "hack" I can really write a short implementation of what I want (my answer below) relying on theinstance ToJSON Key
, but that's ugly. The generic bit of code that works in such defaultinstance ToJSON Key
could be directly used here, instead of the non-total λ. – imz -- Ivan ZakharyaschevKey
data. – imz -- Ivan Zakharyaschev