This function (with httpLBS) works:
makeRequest = do
response <- httpLBS "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
But this function (with httpJSON) does not:
makeRequest = do
response <- httpJSON "http://httpbin.org/get"
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
It throws the error:
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.
Compare the types of
httpLBSandhttpJSON:Notice that
httpLBSalways produces aResponse ByteString, buthttpLBSproducesResponse a. What does that mean?In this case, it means that
httpJSONcan produce aResponsecontaining anything at all with aFromJSONinstance, and it’s up to the function’s caller to decide. How does the caller decide? By specifying the type! This is one of the most interesting properties of Haskell’s typeclasses: the behavior of your program is determined by its types.Of course, most of the time, you don’t see those types, because they are inferred. For example, if you write the following program, you will not need to write any type annotations:
Even though the
idfunction has typea -> a, GHC can infer that there is clearly only one choice fora,Bool, so it is chosen. However, consider your program—how can GHC know whatais supposed to be? Theresponseresult is only used in one place,getResponseStatusCode, which has the following type signature:This function also works on any
Response a, so GHC still can’t decide what theashould be: according to GHC’s terminology, theavariable is ambiguous. The trouble is that picking a specific type forais necessary, since it needs to know whichFromJSONinstance to use to parse the response body.In order to solve this problem, you can disambiguate the expression by supplying your own type annotation, forcing GHC to pick a particular type for
a:Of course, you should replace
()with whatever type represents the structure of the JSON you expect the response to produce.