Home > Software design >  Infer a type from a string in Haskell
Infer a type from a string in Haskell

Time:07-05

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).

  • Related