Tom*_*ane 4 haskell http-conduit
此功能(使用httpLBS)有效:
makeRequest = do
response <- httpLBS "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
Run Code Online (Sandbox Code Playgroud)
但是这个函数(使用httpJSON)不会:
makeRequest = do
response <- httpJSON "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
Run Code Online (Sandbox Code Playgroud)
它抛出错误:
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.
Run Code Online (Sandbox Code Playgroud)
Ale*_*ing 11
比较类型httpLBS和httpJSON:
httpLBS :: MonadIO m => Request -> m (Response ByteString)
httpJSON :: (MonadIO m, FromJSON a) => Request -> m (Response a )
Run Code Online (Sandbox Code Playgroud)
请注意,httpLBS 始终生成a Response ByteString,但httpLBS生成Response a.那是什么意思?
在这种情况下,它意味着httpJSON可以Response使用FromJSON实例生成包含任何内容的任何内容,并且由函数的调用者决定.来电者如何决定?通过指定类型!这是Haskell的类型类中最有趣的属性之一:程序的行为由其类型决定.
当然,大多数时候,你没有看到那些类型,因为它们是推断的.例如,如果编写以下程序,则无需编写任何类型的注释:
ghci> id True
True
Run Code Online (Sandbox Code Playgroud)
即使id函数类型a -> a,GHC可以推断,显然只有一个可供选择a,Bool,所以它选择.但是,考虑一下你的程序 - GHC如何知道a应该是什么?的response结果仅在一个地方使用的,getResponseStatusCode,其具有以下类型签名:
getResponseStatusCode :: Response a -> Int
Run Code Online (Sandbox Code Playgroud)
这个功能也适用于任何一个 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)
Run Code Online (Sandbox Code Playgroud)
当然,您应该()用任何类型替换代表您期望响应生成的JSON结构.