I have a (valid) json encoded array that has missing or malformed data. I want Aeson to turn that into Maybe [Maybe Point]
and have Nothing
where the array element was not a valid Point
.
import Data.Aeson
decode "[1,2,3,4,null,\"hello\"]" :: (Maybe [Maybe Int])
=> Nothing
But I would much rather have it evaluate to
=> Just [Just 1, Just 2, Just 3, Just 4, Nothing, Nothing]
If this can't be done with Aeson, is there another library that can do it?
Note that the actual object is much more complex than a simple integer so string manipulations are not a viable solution.
To begin with, your expected result is not of type
(Maybe [Maybe Int])
, but of type[Maybe Int]
.Secondly, as of the definition of
decode
, this is not possible. Yet, you could usedecode
to decode the JSON array into a list of Aeson Values, which then you can map over and decode the actual values.Thus, a parser error for a single value does not result in a parser error for the whole array.
Edit: As you modified your expectations, this might help you:
From there, you can map and match such that it fits your needs (because just rounding floats may not be suiteable).
We can create a newtype around
Maybe
that doesn't fail when parsing fails, but instead succeeds withNothing
:Now we can wrap types with
Maybe'
to get the desired behavior:However, there's a good chance we want to work with regular
Maybe
values afterwards.Data.Coerce
comes handy here, since it lets us coerce allMaybe'
-s toMaybe
-s, no matter where they are in the result type:I would use Values and work from them:
So
A very ineffective (but safe) solution would be:
If you want to make things more effective you might want to use
Vector
s andfoldl'
.