json - 试图解析递归 JSON,我在正确的轨道上吗?

标签 json haskell recursion abstract-data-type

此问题与this有关题。

这是我希望从 JSON 生成的数据类型:

data ProdObject = MKSpair (Text, Text)
                | MKSLpair (Text, [Text])
                | MKSOpair (Text, ProdObject)
                | MKObject ProdObject
                | End
                deriving Show

Here是我正在处理的数据样本,以及整体的概括。

这是我的实例定义,它导致了错误。我用过 this作为引用。我不确定错误是告诉我要修复我的类型,还是我已经离开了。如果错误真的很直接,我想要一些关于如何修复我的类型的建议,以及关于我可能做错了什么但还没有注意到的任何建议。
instance FromJSON ProdObject where
  parseJSON (Object o) = MKObject <$> parseJSON o
  parseJSON (String s, String t)  = MKSpair (s, t)
  parseJSON (String s, Object o)  = MKSOpair (s, MKObject <$> parseJSON o)
  parseJSON (String s, Array a) = MKSLpair (s, V.toList a)
  parseJSON (Done d) = End
  parseJSON _        = mzero

这是我现在遇到的错误:
ghcifoo> :load test
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:23:52:
    Couldn't match expected type `Value'
                with actual type `Data.Map.Map Text Value'
    Expected type: Value
      Actual type: Object
    In the first argument of `parseJSON', namely `o'
    In the second argument of `(<$>)', namely `parseJSON o'
Failed, modules loaded: none.

更新:我已经重做我的数据类型,如果我是对的,我有一个幻像类型。如果我错了,回到绘图板
data ProdObject = MKSpair (Text, Text)
                | MKSLpair (Text, [Text])
                | MKSOpair (Text, ProdObject)
                | MKObject ProdObject (k,v)
                | End

我也在我的实例中反射(reflect)了这种变化,尽管以不完整的方式。我提到这个只是为了问我是否在正确的轨道上。
parseJSON (Object (k,v)) = MKObject ...

如果我在正确的轨道上,我想我可以弄清楚其余的,或者至少问一个具体的问题。反馈任何人?

最佳答案

在这个等式中:

parseJSON (Object o) = MKObject <$> parseJSON o
o有类型 Map Text Value ,但是 parseJSON有类型 Value -> Parser a ,所以你显然不能申请 parseJSONo .

此外,您在这里有一个类型错误:
parseJSON (String s, String t)  = MKSpair (s, t)
parseJSON的类型是 Value -> Parser a ,但您正在尝试匹配 (Value, Value) .

这同样适用于这一行:
parseJSON (Done d) = End
Done不是 Value 类型的构造函数.

我不明白你为什么需要 ProdObject类型是递归的;这是我解决这个问题的方法:
data Outer = Outer {
  oName :: Text,
  oProducts :: M.Map Text Inner
} deriving Show

data Inner = Inner {
  iQA :: Text,
  iVM :: Text,
  iAvailable :: V.Vector Text
} deriving Show

instance FromJSON Outer where
    parseJSON (Object o) = Outer <$> o .: "name" <*> o .: "products"
    parseJSON _ = mzero

instance FromJSON Inner where
  parseJSON (Object o) = Inner <$> o .: "qa" <*> o .: "vm" <*> o .: "available"
  parseJSON _ = mzero

可以找到完整的代码 list on Github .

关于json - 试图解析递归 JSON,我在正确的轨道上吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7800272/

相关文章:

haskell - 合理的 Comonad 实现

Haskell 类型类混淆

haskell - Haskell 中的并发文件读/写?

python - 骑士在 6x6 数组上的巡回算法仅适用于索引 [0, 0]

Ruby:使用 JSON 正文 PUT 请求?

ios - 在 SWIFT 3 中从网页中读取 JSON 格式

java - Java 中的偶数

c - C 中的递归函数

C++ RapidJSON 清除写入的字符串

json - 如何在表格 View 中创建通知徽章