simpleHTTP
是多态的。包含的响应主体可以是严格的ByteString
,惰性ByteString
或String
中的任意一种。它会选择其中的一个匹配传递给它的值Request ty
。不幸的是,HTTP
是一个古老的图书馆,维护得不好 - 它最低限度地增加了与这三种类型一起工作所必需的多态性,但并非处处都可以使图书馆友好使用。例如,使用getRequest
强制响应为String
,取消simpleHTTP
中的多态性。
下面是一个最简单的工作示例,它抓取该URL的内容,并使用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
对代码中的类型所说的话。
它确实是'HTTP'包中的'simpleHTTP'。我怎样才能告诉它使用正确的'ByteString',这样我就可以将它提供给'decode'函数? – BinRoot
@Nick只需将它提供给'decode'函数即可。这就是确保它是正确的类型所需要的。这是整个类型推断的要点。 – Carl
得到'rsp'之后,我尝试了'sb < - getResponseBody rsp'然后'decode sb',但是由于它期望'Data.ByteString.Lazy.Internal.ByteString'而导致类型错误失败, Char]' – BinRoot