我是Haskell的初学者,我正在尝试使用https://hackage.haskell.org/package/json-0.9.1/docs/Text-JSON.html来解析JSON文档。
在我的任务中,我获得了一个JSON文档,我想返回对应于“index”的值,例如在以下情况中:
{
"root": [
{
"root1": 157538
},
{
"root2": [
{
"leaf21": 3
}
]
},
{
"root3": [
{
"leaf31": "somestring"
},
{
"index": "foundit"
}
]
}
]
}
具体来说:如果出现JSON文档和“root”之类的路径 - > “root3” - > “索引”存在,我想返回“foundit”,否则我想返回Nothing。文档中的其他内容都是任意的:root3,root2,root1,root可能存在也可能不存在等。
现在我可以使用大量的case语句和模式匹配来做到这一点,但是阅读了https://wiki.haskell.org/All_About_Monads,我想知道是否有更好的方法使用类似于Maybe Monad和羊克隆示例的东西,但是我不知道如何编写绑定函数...
[在我的实际案例中,我寻求的价值实际上是文件的19深,所以我有很多案例陈述]
请问你能建议如何使用Monads吗?
答案 0 :(得分:3)
case
语句不是必需的你的猜测是正确的 - 但在这种情况下monad不是正确的答案(没有双关语意图 1 )。
这对Traversals
,Prisms
和Lenses
来说非常棒 - 当然还有伟大的aeson - 库和lens-aeson。
{-# LANGUAGE OverloadedStrings #-}
module Test where
import Control.Lens
import Data.Aeson
import Data.Aeson.Lens
import Data.Monoid ((<>))
jsonString = "{\"root\":[{\"root1\":157538}"
<> ",{\"root2\":[{\"leaf21\":3}]}"
<> ",{\"root3\":[{\"leaf31\":\"somestring\"}"
<> ",{\"index\":\"foundit\"}]}]}"
val :: Maybe Value
val = decode jsonString
indexMaybe :: Maybe Value
indexMaybe = val ^? _Just . key "root" . values
. key "root3" . values
. key "index"
decode
将ByteString
转换为Maybe Value
- Maybe
,因为解析可能会失败!
然后(^?)
运算符预览遍历 - 即它通过JSON对象并遵循您给出的json路径;
为此,您至少要知道“索引”的路径,如果此路径未知,您必须对镜头/棱镜/遍历进行更多研究,或者对解析后的对象进行简单的树搜索
对于那些没时间在json对象中实现搜索“index”的人来说,这是一个扰流器:
search :: Text -> Value -> Maybe Value search txt o@(Object o') = let f y@(Just x) _ = y f _ v = search txt v in case o ^? key txt of Nothing -> foldl' f Nothing o' x -> x search txt a@(Array a') = let f y@(Just x) _ = y f _ v = search txt v in foldl' f Nothing a' search _ _ = Nothing
正如@MarkSeeman已经提到的 - 一个简单的文本搜索,可能会更有效率。
1 :好吧可能有点