Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Unexpected behavior of .:? #83

Open
lykahb opened this Issue · 3 comments

2 participants

@lykahb

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
@bos
Owner
bos commented

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

@bos
Owner
bos commented

cc @ffwng

@lykahb lykahb referenced this issue from a commit in lykahb/aeson
Boris Lykah Fix .:? behavior for #83 5ae3d04
@lykahb lykahb referenced this issue from a commit in lykahb/aeson
Boris Lykah Fix .:? behavior for #83 39f188a
@lykahb lykahb referenced this issue from a commit in lykahb/aeson
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 referenced this issue from a commit
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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.