簡體   English   中英

為什么httpJSON失敗,但httpLBS成功了?

[英]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.

比較httpLBShttpJSON的類型:

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也可以推斷出aBool只有一個選擇,所以選擇它。 然而,考慮你的程序如何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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM