Unexpected behavior of .:? #83

Closed
lykahb opened this Issue Jul 5, 2012 · 5 comments

Comments

Projects
None yet
3 participants

lykahb commented Jul 5, 2012

I want to have distinction between absence of field and its null value.

data Blah = Blah (Maybe (Maybe String))
instance FromJSON Blah where
  parseJSON (Object v) = Blah <$> v .:? "blah"
Blah Nothing -- if field not mentioned
Blah (Just Nothing) -- if field has null value

However, the result of parsing is never Blah (Just Nothing) because .:? uses (Maybe a) instance directly.

(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
obj .:? key = case H.lookup key obj of
               Nothing -> pure Nothing
               Just v  -> parseJSON v
            -- Just v  -> Just <$> parseJSON v would have expected behavior
Owner

bos commented Sep 4, 2013

The obvious fix for this breaks some of the test suite, and I haven't had a chance to diagnose that yet. Looking.

Owner

bos commented Sep 4, 2013

cc @ffwng

@lykahb lykahb pushed a commit to lykahb/aeson that referenced this issue Dec 18, 2014

Boris Lykah Fix .:? behavior for #83 5ae3d04

@lykahb lykahb pushed a commit to lykahb/aeson that referenced this issue Jul 21, 2015

Boris Lykah Fix .:? behavior for #83 39f188a

@lykahb lykahb pushed a commit to lykahb/aeson that referenced this issue Jul 21, 2015

Boris Lykah Fix .:? behavior for #83
It makes (.:?) return Just value if the key is present for values of type Maybe a.
Earlier {"key": null} .:? "key" would return Nothing although the key is there. It was not possible to distinguish the cases when key is absent and when value is null.
Now it treats Maybe same way as other types and returns Just Nothing.
e6877ac

@bos bos pushed a commit that referenced this issue Aug 11, 2015

Boris Lykah Fix .:? behavior for #83
It makes (.:?) return Just value if the key is present for values of type Maybe a.
Earlier {"key": null} .:? "key" would return Nothing although the key is there. It was not possible to distinguish the cases when key is absent and when value is null.
Now it treats Maybe same way as other types and returns Just Nothing.
d0414be

lykahb commented Aug 11, 2015

Writing a testcase was harder than I expected since monadic Parser does not play well with properties.

isExistingKeyJust :: Value -> Bool
isExistingKeyJust (Object obj) = all (\k -> isJust $ obj .:? k) $ H.keys obj -- does not typecheck
isExistingKeyJust _ = False

MaxGabriel referenced this issue in yesodweb/persistent Sep 5, 2015

Closed

Not ready for aeson 0.10 #465

Contributor

gregwebs commented Sep 5, 2015

This is committed as d0414be
However, it is not in the Changelog even though this is a huge breaking change.
I personally like the change, however, I think it may cause so much breakage that the existing behavior should be maintained and a different operator should be added instead., perhaps .:??

Contributor

gregwebs commented Sep 21, 2015

Should this be closed now?

bos closed this Sep 22, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment