PureScript beginner here.
Let’s assume the following API response
testJSON1 :: String
testJSON1 = """
[
-- | A
{ "apple": "Hello"
, "banana": [ 1, 2, 3 ]
},
-- | B
{ "bax": 5 },
-- | C
{ "foo": "bar"
, "bax": "now it's a string"
}
]
"""
which I could model with a sum type. But let’s say that my code only knows how to handle A and B and doesn’t care about C and all other possible shapes.
How would I best represent this in PureScript and also decode it, ideally with Simple.JSON
?
A sum type wouldn’t work because every time a new possible thing is added (D, E,…) I’d have to update my sum type.
I also can’t just make it an extensible record, because here the key bax
has a different type depending on which thing it is.
At first variants sounded like something that would work but according to purescript-option
they’re apparently about key/value rather than optional records as a whole:
Variants capture the idea of a collection of key/value pairs where exactly one of the key/value pairs exist. E.g.
Data.Variant.Variant (foo :: Boolean, bar :: Int)
means that either onlyfoo
exists with a value or onlybar
exists with a value, but not both at the same time.Options capture the idea of a collection of key/value pairs where any key and value may or may not exist. E.g.
Option.Option (foo :: Boolean, bar :: Int)
means that either onlyfoo
exists with a value, onlybar
exists with a value, bothfoo
andbar
exist with values, or neitherfoo
norbar
exist.
so I guess I need something like type Thing = forall v. A | B | v
. I really thought that a variant
type A
= { foo :: String }
type Things
= forall v. Variant ( a :: A | v )
would work but I don’t know how to make this work with Simple.JSON
. It’s current variant handling seems to expect objects of type { type: ..., value: ...}
, for the variants unless I’m misunderstanding something here.
Maybe I’m overlooking some excellent documentation here but I couldn’t find any guidance on how to only handle a subset of objects in an array from a JSON response with PureScript.
EDIT: I guess I could just define a newtype
wrapper and just implement my own decoding logic where I try to decode each object in the array into a known sumtype and if it fails I just ignore it. But I’d have to repeat this for every such array of objects and I’m sure there’s a nicer generic solution.