
On Tue, Dec 16, 2014 at 08:43:08AM +0000, Michael Snoyman wrote:
On Tue Dec 16 2014 at 10:39:32 AM Tobias Dammers
wrote: On Mon, Dec 15, 2014 at 11:01:12PM +0100, Wojtek NarczyĆski wrote:
On 15.12.2014 20:32, Tobias Dammers wrote:
Anyway, one thing I'm running up against is that I am going to need ordered key/value collections, which I believe is something JSON does not support out-of-the-box: "objects" ({"foo":15, "bar":23}) are conceptually unordered key/value collections (and Aeson treats them as such, using hash maps as the intermediate storage format), so I lose ordering;
JSON does not forbid ordering of maps by key, I believe. But you'd need to create an OrderedMap and patch aeson. It would be very useful, the mixing of key order is nuisance for human JSON consumers.
No, that's not what I meant. By "ordered", I meant that the in-memory representation of the document should maintain file order. Aeson uses a HashMap to store key/value objects, which is an unordered container; what you suggest would be something like Map (storing elements by key order), but what I'm talking about is more like [(Key, Value)], i.e., keeping file order intact.
I think your best bet is to bite the bullet and just deal with an array, forgetting the object entirely (at least at the top level). Any time I've needed to implement some kind of ordered data in JSON, I've used an array.
Yes, that's what I was thinking myself. I absolutely don't want to use "looks like JSON but isn't", I really want to stick with standard JSON, for so many reasons. My tentative design so far is to use an array of "anything"; each element can be a scalar (which generates an unnamed field), an object with the magic properties "_name" and "_value", which generates a named field, or something else, which generates an unnamed field containing that something else. So I'd have this: [ "foobar" , { "baz": "quux", "boink": "blip" } , { "_name": "foobar", "_value": "oink" } , { "_name": "quuux", "_value": { "apples": "oranges" } } ] ...which would map to something like (in pseudo-Show notation): [ ("_field_1", String "foobar") , ("_field_2", Object (fromList [ ("baz", "quux"), ("boink", "blip") ])) , ("foobar", String "boink") , ("quuux", Object (fromList [ ("apples": "oranges") ])) ] This would meet the requirement of providing ordered properties, and it would allow for arbitrary JSON (i.e., the mapping would be total over all valid JSON arrays); the downside is that the ToJSON and FromJSON instances for my Record type would be a bit more complex than what I have now, but I guess that would be OK. Another downside would be that if an element specifies both "_value" *and* non-magic fields, I would have to decide whether I want to treat "_value" as non-magic, or throw away the non-magical fields.