-
Notifications
You must be signed in to change notification settings - Fork 323
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
Duplicate keys #531
Comments
Thank you for your report. It definitely doesn't look intentional, thanks for pinpointing it @Lysxia! So I don't think there is a workaround, unfortunately. I'd be inclined to say that you should not depend on this behavior as it's not in the JSON spec. The fact that we allowed this to begin with might have just been an accidental result caused by how @winterland1989 do you remember if there was a reason this changed? Performance? |
Yep, |
Thanks for the responses. IMHO, it would be convenient if aeson followed ECMAScript's specification of
At the very least, the current behavior should be considered part of the API. Thanks for your consideration and for all of your hard work on this package. |
OK, if we choose to follow that convention, i believe we should just use stack space to build the list directly(which may bring some performance improvement):
|
@winterland1989 Have you considered only replacing |
Good idea! I suppose that would work too, also it would keep the constant stack behavior. |
Since Aeson uses a HashMap to represent objects, I think it should fail to parse JSON that has duplicate keys, rather than silently ignoring some of the input. With the current behavior (no matter if it picks the first or last occurrence) there is no way for the application to know that part of the input was ignored, and take action (e.g., warn the user, or reject the input as invalid). |
I was going to argue that allowing duplicates was in line with the "tolerant reader" approach aeson uses otherwise such as ignoring extraneous fields, but I wasn't able to turn this into a proper argument :) I don't think the current internal representation should influence this decision. But the alternative would be to change it to HashMap Text [Value], I don't think I want to go down that road. @cydparser would turning duplicate keys into an error work in your case or do you actually need this behavior? The purist in me says that this should indeed be a parse error. |
@bergmark I needed the treatment of duplicate keys to match ECMAScript -- throwing an error would not have helped. I am validating a JSON configuration file that is preprocessed (custom template rules and string interpolation) and parsed by Node.js. It is the Node.js app that ultimately relies on the behavior of duplicate keys, so the Haskell code must allow them too. I have a workaround in place. I would argue that most uses of JSON involve parsing with ECMAscript at some point, and that deviating from its behavior too much violates the principle of least surprise. It is reasonable to expect that parsing JSON directly with Haskell and parsing JSON posted from a web service that does nothing but |
We could parametrize the behavior of the parser, e.g., using something like: data DuplicateKeys = RejectDuplicates | UseLaterEntry |
I'd just like to point out that RFC7159 (which I consider the most accurate specification of JSON currently), has to say the following about duplicates:
|
It's rfc8259 now, but the message still holds. OTOH the ability to know there were duplicates (or, a stricter parser) would be welcome too I think. |
hello @bergmark, i use the Proposal from @yav may could help me. data DuplicateKeys = RejectDuplicates | UseLaterEntry |
- This allows explicit handling of duplicate keys. - Also remove an outdated comment about the difference between the parsers value and json (they have been the same for a while).
@Lysxia kindly added configurable support for this. Please try out the 1.4.4.0 release. |
The behavior of parsing duplicate keys has changed from last key wins to first key wins. I do not see any mention of this change in the changelog -- was it intentional? Is there a way to force the previous behavior?
E.g. With aeson-0.11.2.1:
Version 1.0.2.1 results in
Just (fromList [("a",Bool False)])
.The text was updated successfully, but these errors were encountered: