1

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!

1 Answer 1

4

Do you want to build parseJSON? It doesn't have to be parseJSON...

abParser :: String -> Value -> Parser MyRecord
abParser valueC = withObject "MyRecord" $ \o -> do
    valueA <- o .: "a"
    valueB <- o .: "b"
    return MyRecord { a = valueA, b = valueB, c = valueC }

createMyRecord :: ByteString -> String -> Maybe MyRecord
createMyRecord json valueC = decode json >>= parseMaybe (abParser valueC)
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, thank you! I knew there was a simple solution but was struggling to work it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.