网络服务返回ByteString
req <- parseUrl "https://api.example.com"
res <- withManager $ httpLbs $ configReq req
case (HashMap.lookup "result" $ responseBody res) of .... -- error - responseBody returns ByteString
where
configReq r = --......
更具体地说,responseBody
会返回ByteString
中的数据,尽管它实际上是有效的JSON。我需要在其中找到一个值。显然,如果它是JSON而不是ByteString
,那么找到它会更容易。
如果是这种情况,我该如何将其转换为JSON?
更新:
decode $ responseBody resp :: IO (Either String Aeson.Value)
错误:
Couldn't match expected type `IO (Either String Value)'
with actual type `Maybe a0'
答案 0 :(得分:2)
您将找到几个用于将bytestring转换为JSON的资源。最简单的用例是在hackage页面本身,其余的你可以推断使用所涉及实体的类型签名。
https://hackage.haskell.org/package/aeson-0.7.0.6/docs/Data-Aeson.html
但是这是Aeson与JSON的超级快速介绍: 在大多数语言中,你有这样的东西:
someString = '{ "name" : ["value1", 2] }'
aDict = json.loads(someString)
这显然很棒,因为JSON具有与该语言的基本数据结构几乎一对一的映射。大多数动态语言中的容器可以包含任何类型的值,因此从JSON迁移到数据结构只需一步。
然而,Haskell并非如此。您不能将任意类型的东西放入类型(列表或字典)之类的容器中。
所以Aeson做了一件好事。它为您定义了一个中间Haskell类型,它直接映射到JSON。
Aeson
中的基本单位是Value
。价值可以包含很多东西。像整数,字符串,数组或对象一样。
https://hackage.haskell.org/package/aeson-0.7.0.6/docs/Data-Aeson.html#t:Value
aeson数组是Vector
的{{1}}(如同列表但更好),Value
和aeson对象是HashMap
Text
到Value
的{{1}}小号
下一个有趣的步骤是您可以定义将Aeson值转换为Haskell类型的函数。这样就完成了循环。自定义类型的ByteString
到Value
。
所以你要做的就是实现{a {1}}和parseJSON
函数,将aeson值转换为你的类型,反之亦然。将字节串转换为有效的aeson值的位由aeson实现。因此,繁重的工作都已完成。
重要的是要注意,Aeson bytestring是一个懒惰的字节串,所以你可能需要一些严格的懒惰助手。
toJSON
这应该足以开始使用Aeson。
-
Aeson的常见解码功能:
stringToLazy :: String -> ByteString
stringToLazy x = Data.Bytestring.Lazy.fromChunks [(Data.ByteString.Char8.pack x)]
lazyToString :: ByteString -> String
lazyToString x = Data.ByteString.Char8.unpack $ Data.ByteString.Char8.concat $ Data.ByteString.Lazy.toChunks
在你的情况下,你正在寻找代码。