Reputation: 19724
I'm testing out some functions in ghci before I put them into a project, and I'm straining to find the simplest way to enter json literals in the ghci without a ton of boilerplate
For example, I'd like to try out:
myFuncThatTakesAJson
on inputs
x = {}
y = {"a": 1}
But when I try entering these:
import Text.JSON
Prelude> x = parseJSON "{}"
Prelude> y = parseJSON "{'a' : 1}"
I see errors like:
<interactive>:17:5: error:
Variable not in scope: parseJSON :: [Char] -> t
y = fromJSON "{'a' : 1}"
<interactive>:20:5: error:
Data constructor not in scope: FromJSON :: [Char] -> t
Is there any way to allow json objects to be entered as strings without defining full data types with custom FromJSON instances?
Upvotes: 1
Views: 318
Reputation: 32319
There sure is! The type of a raw JSON value is Value
. With that in mind, here's a couple of ways of constructing a Value
in GHCi:
with parseJSON
: since Value
also has a FromJSON
instance, you can use decode :: FromJSON a => ByteString -> Maybe a
on it. Note that aeson
is encouraging you to use ByteString
instead of the inefficient default String
. You can gloss over this detail by making string literals be overloaded by turning on -XOverloadedStrings
:
ghci> import Data.ByteString
ghci> import Data.Aeson
ghci> :set -XOverloadedStrings
ghci> x = decode "{}" :: Maybe Value
x :: Maybe Value
ghci> y = decode "{\"a\" : 1}" :: Maybe Value -- note: single quotes won't work
y :: Maybe Value
with quasiquotes: you can also make use of the aesonQQ
quasiquoter to get compile time JSON literals (this won't matter much in the REPL, beyond looking nicer, but in real code it means no actual parsing at runtime):
ghci> import Data.Aeson.QQ.Simple
ghci> :set -XQuasiQuotes
ghci> x = [aesonQQ| {} |]
x :: Value
ghci> y = [aesonQQ| {"a" : 1} |]
y :: Value
Upvotes: 3