[英]Why does this first Haskell function FAIL to handle infinite lists, while this second snippet SUCCEEDS with infinite lists?
[英]Why does httpJSON fail, but httpLBS succeeds?
此功能(使用httpLBS)有效:
makeRequest = do
response <- httpLBS "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
但是这个函数(使用httpJSON)不会:
makeRequest = do
response <- httpJSON "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
它抛出错误:
Ambiguous type variable `a0' arising from a use of `httpJSON' prevents the constraint
`(aeson-1.1.2.0:Data.Aeson.Types.FromJSON.FromJSON a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
比较httpLBS
和httpJSON
的类型:
httpLBS :: MonadIO m => Request -> m (Response ByteString)
httpJSON :: (MonadIO m, FromJSON a) => Request -> m (Response a )
请注意, httpLBS
始终生成Response ByteString
,但httpLBS
生成Response a
。 这意味着什么?
在这种情况下,这意味着httpJSON
可以使用FromJSON
实例生成包含任何内容的Response
,并且由函数的调用者决定。 来电者如何决定? 通过指定类型! 这是Haskell的类型类中最有趣的属性之一:程序的行为由其类型决定。
当然,大多数时候,你没有看到那些类型,因为它们是推断的。 例如,如果编写以下程序,则无需编写任何类型的注释:
ghci> id True
True
即使id
函数具有类型a -> a
,GHC也可以推断出a
, Bool
只有一个选择,所以选择它。 然而,考虑你的程序如何GHC知道什么是a
应该是? response
结果仅在一个地方使用, getResponseStatusCode
,具有以下类型签名:
getResponseStatusCode :: Response a -> Int
此函数也适用于任何 Response a
,因此GHC仍然无法确定a
应该是什么:根据GHC的术语, a
变量是不明确的 。 问题是为a
选择特定类型是必要的,因为它需要知道使用哪个FromJSON
实例来解析响应主体。
为了解决这个问题,你可以通过提供自己的类型注释,迫使GHC选择一个特定类型的歧义表达a
:
makeRequest = do
response <- httpJSON "http://httpbin.org/get" :: IO (Response ())
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
当然,你应该用任何代表你希望响应产生的JSON结构的类型替换()
。
不确定这是否对其他人有帮助,但它帮助了我。 我尝试了::IO (Response ())
注释,我得到了完整的打印响应然后"expected (), encountered Object"
,并将其切换到:: IO (Response Object)
修复它只是输出
λ makeRequest
200
it :: ()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.