I have a record that I want to construct with some values from a JSON string as well as some additionally provided values.
For example - given the following record:
data MyRecord = MyRecord { a :: String, b :: Int, c :: String }
I want do define a function:
createMyRecord :: String -> String -> Maybe MyRecord
createMyRecord json cValue = ???
Which I want to be able to call like so:
createMyRecord "{\"a\": \"a value\", \"b\": 100}" "c value"
Currently, I'm doing this by use Aeson to create the record with defaults (i.e. empty strings and zeros) for the values which don't come from the JSON. I then create a new version of the record with the other fields updated. Something like this:
instance FromJSON MyRecord where
parseJSON = withObject "MyRecord" $ \o -> do
valueA <- o .: "a"
valueB <- o .: "b"
return MyRecord { a = valueA, b = valueB, c = "" }
createMyRecord :: String -> String -> Maybe MyRecord
createMyRecord json cValue =
Aeson.decode json <$> (\r -> r { c = cValue })
This feels a bit cumbersome - I'd like to create the record in one go with all the values, rather than filling them in step by step. Is there a nicer way to do this with Aeson (I'm open to other libraries also) that anyone can recommend?
Thanks!