尝试解析递归 JSON,我走在正确的轨道上吗?

发布于 2024-12-10 13:58:50 字数 2010 浏览 0 评论 0原文

此问题与 这个问题。

以下是我希望从 JSON 创建的数据类型:

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

这里 是我正在使用的数据的示例,加上整体的概括。

这是我的实例定义,它导致了错误。我使用这个作为参考。我不确定这个错误是否告诉我要修复我的类型,或者我已经偏离了。如果错误确实是直接的,我想要一些关于如何修复我的类型的建议,以及关于我可能做错但还没有注意到的其他内容的建议。

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 ...

如果我走在正确的轨道上,我想我可以弄清楚剩下的事情,或者至少问一个具体的问题。有人反馈吗?

This problem is related to this question.

Here is the data type I wish to make from the JSON:

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

Here is a sample of the data I am working with, plus a generalization of the whole.

Here's my instance definition, which is causing an error. I've used this as a reference. I'm not sure if the error is telling me to fix my type, or that I'm way off. If the error really is straight-forward, I'd like some advice on how to fix my type,plus any advice on what else I may be doing wrong but haven't noticed yet.

instance FromJSON ProdObject where
  parseJSON (Object o) = MKObject <
gt; parseJSON o
  parseJSON (String s, String t)  = MKSpair (s, t)
  parseJSON (String s, Object o)  = MKSOpair (s, MKObject <
gt; parseJSON o)
  parseJSON (String s, Array a) = MKSLpair (s, V.toList a)
  parseJSON (Done d) = End
  parseJSON _        = mzero

Here's the error I have right now:

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 `(<
gt;)', namely `parseJSON o'
Failed, modules loaded: none.

Update: I've redone my data type, if I'm right I've got a phantom type. If I'm wrong, back to the drawing board

data ProdObject = MKSpair (Text, Text)
                | MKSLpair (Text, [Text])
                | MKSOpair (Text, ProdObject)
                | MKObject ProdObject (k,v)
                | End

Also I have reflected this change in my instance, though in an incomplete manner. I mention this just to ask if I am on the right track or not.

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

If I'm on the right track, I think I can either figure out the rest, or at least ask a specific question. Feedback anyone?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇妻 2024-12-17 13:58:50

在此等式中:

parseJSON (Object o) = MKObject <
gt; parseJSON o

o 的类型为 Map Text Value,但 parseJSON 的类型为 Value ->;解析器 a,因此显然不能将 parseJSON 应用于 o

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

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

parseJSON 的类型是 Value ->解析器 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 <
gt; o .: "name" <*> o .: "products"
    parseJSON _ = mzero

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

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

In this equation:

parseJSON (Object o) = MKObject <
gt; parseJSON o

o has type Map Text Value, but parseJSON has type Value -> Parser a, so you obviously can't apply parseJSON to o.

Also, you have a type error here:

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

The type of parseJSON is Value -> Parser a, but you are trying to match against (Value, Value).

The same applies to this line:

parseJSON (Done d) = End

Done is not a constructor of type Value.


I couldn't understand why you need the ProdObject type to be recursive; here's how I would solve this problem:

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 <
gt; o .: "name" <*> o .: "products"
    parseJSON _ = mzero

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

Full code listing can be found on Github.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文