【问题标题】:Trying to parse recursive JSON, am I on the right track?尝试解析递归 JSON,我在正确的轨道上吗?
【发布时间】:2011-12-09 15:49:55
【问题描述】:

此问题与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

我也在我的实例中反映了这种变化,尽管方式不完整。我提到这只是想问我是否走在正确的轨道上。

parseJSON (Object (k,v)) = MKObject ...

如果我走在正确的轨道上,我想我可以弄清楚其余部分,或者至少提出一个具体问题。有人反馈吗?

【问题讨论】:

    标签: json haskell recursion abstract-data-type


    【解决方案1】:

    在这个等式中:

    parseJSON (Object o) = MKObject <$> parseJSON o
    

    o 的类型为Map Text Value,但parseJSON 的类型为Value -&gt; Parser a,因此您显然不能将parseJSON 应用于o

    另外,这里有一个类型错误:

    parseJSON (String s, String t)  = MKSpair (s, t)
    

    parseJSON 的类型是 Value -&gt; 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
    

    完整的代码清单可以在on Github找到。

    【讨论】:

    • 我认为我对 JSON 对象的外观有错误的概念。
    • 我认为它需要递归,因为我收到的数据在我看来是递归的。感谢您的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    相关资源
    最近更新 更多