I am trying to write a FromJSON
implementation which would parse a list of objects while at the same time skipping some of them - those which contain a certain json property.
I have the code like this, but without proper handling of mzero it returns an error once it encounters a value with "exclude: true".
newtype Response = Response [Foo]
newtype Foo = Foo Text
instance FromJSON Response where
parseJSON = withArray "Foos" $ \arr -> do
-- can I filter out here the ones which return `mzero`?
foos <- mapM parseJSON arr
pure $ Response (toList foos)
instance FromJSON Foo where
parseJSON = withObject "Foo" $ \foo -> do
isExcluded <- foo .: "exclude"
if isExcluded
then mzero
else do
pure $ Foo "bar"
I've found a few questions which hint at using parseMaybe
, but I can't figure out how I can use it from within the FromJSON
definition, it seems to be more suited to running the parser from "outside". Is it possible to do skipping "inside"? Or am I going the wrong route here?
CodePudding user response:
What you're looking for is the optional function. It can be a bit tricky to find because it's very general-purpose and not simply a helper function in aeson
. For your purposes, it will have the type Parser a -> Parser (Maybe a)
and used in conjunction with catMaybes
should do what you want.