假设我要解析http://reddit.com/r/haskell.json
中的JSONmain = do
rsp <- simpleHTTP (getRequest "http://www.reddit.com/r/haskell.json")
str <- fmap (takeWhile isAscii) (getResponseBody rsp)
我现在有一个准备解析的字符串。但是,Aeson的decode
函数具有以下类型签名:
decode :: FromJSON a =>
bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString -> Maybe a
如何解码该字符串中的JSON?或者有更好的方法来解码GET请求吗?
答案 0 :(得分:4)
simpleHTTP
是多态的。包含的响应正文可以是严格ByteString
,懒惰ByteString
或String
中的任何一种。它选择其中一个以匹配传递给它的Request ty
值。遗憾的是,HTTP
是一个旧的库并且维护得很差 - 它最低限度地添加了处理这三种类型所必需的多态性,但并不是它可以使图书馆友好使用的所有地方。例如,使用getRequest
强制响应为String
,从而使simpleHTTP
中的多态性无效。
以下是使用HTTP
抓取该网址内容并使用aeson
对其进行解码的最小工作示例。
import Network.URI
import Network.HTTP
import Data.Aeson
-- There's absolutely no reason that this function shouldn't be in HTTP.
-- It's just as unsafe and terrible as getRequest is. In fact, this is a
-- strictly more general type than getRequest has, so there's no reason
-- it shouldn't just replace it.
getRequest_ :: HStream ty => String -> Request ty
getRequest_ s = let Just u = parseURI s in defaultGETRequest_ u
main :: IO ()
main = do
rsp <- simpleHTTP $ getRequest_ "http://www.reddit.com/r/haskell.json"
body <- getResponseBody rsp
print (decode $ body :: Maybe Value)
请注意,使用decode
最终确定了simpleHTTP
的多态类型。只是在这个版本中,它与getRequest
关于代码中的类型的说法并不矛盾。