benbrunton
benbrunton

Reputation: 1000

Is it possible to create nested JSON objects in haskell using Text.JSON?

I have a structure which is an object at the top level, containing mainly strings as values and one nested object. It should look something like:

{
  "name" : "expand",
  "type" : "2",
  "code" : "...",
  "options" : {
     "atb" : {
         "description" : "..",
         "value" : true
     }
}

I'm guessing that because JSObject holds a list of key/value pairs, there is no way of mixing different value types on the same level. This seems like a huge limitation so I'm hoping I'm wrong!

Upvotes: 3

Views: 375

Answers (2)

Jonke
Jonke

Reputation: 6533

If you don't already do it with generic, here is a way to use instances of TEXT.JSON

import Text.JSON

data SO = SO {
            name :: String,
            mytype :: Int,
            code :: String,
            options :: [Option]
        } deriving (Show)

data Option =Option {
                atb :: KV
            }


data KV = KV {
                desc :: String,
                v:: Bool
                 }

instance JSON SO where
   showJSON ge = makeObj
          [ ("name", showJSON $ name ge),
            ("type", showJSON $ mytype ge),
            ("options", showJSON $ options ge)
          ]                        
   readJSON = error "readJSON not implemented for SO"


instance JSON Option where
   showJSON ge = makeObj
          [ ("atb", showJSON $ atb ge)
          ]                        
   readJSON = error "readJSON not implemented for Option"

instance JSON KV where
   showJSON ge = makeObj
          [ ("description", showJSON $ desc ge),
          [ ("value", showJSON $ v ge)
          ]                        
   readJSON = error "readJSON not implemented for kv"

--encode $ SO .........

Upvotes: 1

Don Stewart
Don Stewart

Reputation: 137987

Text.JSON allows you to nest objects, as you can see by the type definition:

data JSValue
    = JSNull
    | JSBool     !Bool
    | JSRational !Rational
    | JSString   JSString
    | JSArray    [JSValue]
    | JSObject   (JSObject JSValue)

newtype JSObject e = JSONObject { fromJSObject :: [(String, e)] }

The type is recursive - JSValues may be JSObjects which in turn may be dictionaries of JSValues.

Upvotes: 7

Related Questions