![](/img/trans.png)
[英]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.