I'm working on a JSON data encoder in Haskell! (to be more specific, I am trying to port Jo into Haskell!). I've gotten a lot of it working, but I'm running into a little wrinkle. I'll try to be concise with my question here, I've tried to strip away as much unneeded context as possible.
Goal: Construct a Value
given a String
.
These strings come from the command line: Users enter in key/value pairs in the form <key>=<value>
. After splitting them apart I am left in a String
that is the value data of unknown type.
Example cases:
let s = "someString" -- use the `String` constructor
let s = "1234" -- use the `Number` constructor
let s = "True" -- use the `Bool` constructor
Question: How might I infer that the contents of s
is a String
vs a Number
, Bool
, etc?
This is the relevant type constructors for the Aeson Value
type (edited for brevity).
data Value = Object Object
| Array Array
| String Text
| Number Scientific
| Bool Bool
| Null
CodePudding user response:
Since you're already using the aeson package, you could use decode. This works because Value
is also a ByteString
instance:
Prelude Data.Aeson> decode "\"someString\"" :: Maybe Value
Just (String "someString")
Prelude Data.Aeson> decode "1234" :: Maybe Value
Just (Number 1234.0)
Prelude Data.Aeson> decode "true" :: Maybe Value
Just (Bool True)
Notice (as n. 1.8e9-where's-my-share m. points out in the comments) that strings must be quoted.
What you could do, then, is to take your unknown value and first surround it with quotes and attempt to parse it. Then try to parse it again without surrounding quotes.
You now have two Maybe Value
values. Pick the first Just
value (and be prepared to deal with the Nothing
case).