Aeson匹配二进制树

时间:2014-09-11 14:17:49

标签: haskell binary-tree aeson

我很难尝试解析像

这样的结构
{"tree": [5, [[1, 4], [2, 3]]]}

进入二叉树

data Tree a = Leaf a | Node (Tree a) (Tree a)

但我似乎无法让这些类型正确。这个问题有一个简单的解决方案吗?

我假设每个JSON数组恰好包含两个元素,因此结果应为

Node (Leaf 5) (Node (Node (Leaf 1) (Leaf 4)) (Node (Leaf 2) (Leaf 3))) :: Tree Int

修改:我尝试过:

我尝试添加新数据类型以便导入

data IntTree = IntTree { jsonTree :: Tree Int }

instance FromJSON IntTree
  where
    parseJSON (Object v) = do
        inttree <- (v .: "tree")
        -- now I am stuck

1 个答案:

答案 0 :(得分:1)

当我开始使用Aeson时,我发现FromJSONToJSON类型很有用,但并不真正了解它们是如何工作的。我发现弄乱underlying types that Aeson uses to represent JSON values可能很有教育意义。例如,它对对象使用HashMap,对数组使用Vector

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import qualified Data.HashMap.Strict as H
import qualified Data.Vector as V

j = "{\"tree\": [5, [[1, 4], [2, 3]]]}"

data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Show)

Just (Object decoded) = decode j :: Maybe Value

Just tree = H.lookup "tree" decoded

parse :: FromJSON a => Value -> Tree a
parse t = case t of
    Array v -> if V.length v /= 2
                   then error "Not a binary tree"
                   else Node (parse (V.head v)) (parse (V.last v))
    x       -> Leaf $ case fromJSON x of
                   Success a   -> a
                   Error   msg -> error msg


main = print $ show $ (parse tree :: Tree Int)