Home > Mobile >  How can I parse a JSON-formatted string into Tree Int
How can I parse a JSON-formatted string into Tree Int

Time:11-05

I have the following code:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Tree

main :: IO ()
main = print $ decode "[1,[2,[]]]" :: Maybe (Tree Int)

But the output is "Nothing" in the console. How can I parse JSON data into Tree String, Tree Int types ? As far as I know, Tree v has a fromJSON instance as long as v has a fromJSON instance.

CodePudding user response:

I’m not very familiar with how Aeson defines these instances, so I went looking on Hackage. In the module where this instance is defined, Data.Aeson.Types.ToJSON, I see this code:

instance ToJSON1 Tree.Tree where
    liftToJSON t tol = go
      where
        go (Tree.Node root branches) =
            liftToJSON2 t tol to' tol' (root, branches)

        to' = liftToJSON go (listValue go)
        tol' = liftToJSONList go (listValue go)

    liftToEncoding t tol = go
      where
        go (Tree.Node root branches) =
            liftToEncoding2 t tol to' tol' (root, branches)

        to' = liftToEncoding go (listEncoding go)
        tol' = liftToEncodingList go (listEncoding go)

instance (ToJSON v) => ToJSON (Tree.Tree v) where
    toJSON = toJSON1
    toEncoding = toEncoding1

The call to liftToJSON2 here, and reading instance ToJSON2 (,) and instance ToJSON1 [], tells me that a Node is represented as an array of two elements, where the former is the encoding of the root value, and the latter is the encoding of the branches. Since this is a list, it’s also encoded as an array.

So your example case [1,[2,[]]] is close, but you’re missing one level of nesting—since Tree 1 [Tree 2 []] is encoded via (1, [(2, [])]), I infer that it needs to be [1,[[2,[]]]]. This is probably documented somewhere, but I can’t easily find it.

  • Related