Question: In my PureScript program, I’ve recieved a foreign JSON object, which I expect to have a particular structure. How do I safely “cast” that to a PureScript data type?
Or maybe I don’t have any expectations about the structure of the JSON, and I want to read the JSON and discover its structure?
This is a super common question, and I was using PureScript for years before I figured out what best answers were.
1. Argonaut
The decodeJson
function from argonaut can infer the structure of the JSON you’re expecting from the type of the data that you want to cast it to. If the structure of the JSON doesn’t match the type, then it returns an error in Left
.
show $ do
x :: Array {a::Int,b::String} <- decodeJson =<< parseJson """[{"a":2,"b":"stuff"}]"""
pure x
Results in (Right [{ a: 2, b: "stuff" }])
See the argonaut-codecs Quick start for more decodeJson
examples:
https://pursuit.purescript.org/packages/purescript-argonaut-codecs
If you want to decodeJson
for some type that doesn’t already have a DecodeJson
instance, then you can write a DecodeJson
instance for your type.
If you want to discover the structure of the JSON, you can write monadic parsers in the Either
monad with the getField*
functions. You can also preview
the Json
with Argonaut.Prisms
.
2. Simple.JSON
The Simple.JSON.read'
function can also infer the expected structure of JSON from the PureScipt data type that we are trying to read into.
https://purescript-simple-json.readthedocs.io/en/latest/intro.html
Simple.JSON
also has many more features.
3. F Monad
The most powerful and general way to read foreign data is by writing monadic parsers for the F
monad. You run the parser with runExcept
.
Those are the best answers
I’ve seen my own colleagues and many people on the internet write libraries which duplicate the functions I’ve described here because these answers are hard to find if you’re new to PureScript and you’re not sure what you’re looking for.
The classic essay on the general problem of how to read unstructured untyped data into a typed data structure is Parse, don’t validate and I strongly recommend this essay.