Comparer les types de httpLBS
et httpJSON
:
httpLBS :: MonadIO m => Request -> m (Response ByteString)
httpJSON :: (MonadIO m, FromJSON a) => Request -> m (Response a )
Notez que httpLBS
toujours produit un Response ByteString
, mais httpLBS
produit Response a
. Qu'est-ce que ça veut dire?
Dans ce cas, cela signifie que httpJSON
peut produire un Response
tout ce qui contient du tout avec une instance FromJSON
, et il est à appelant de la fonction de décider. Comment l'appelant décide-t-il? En spécifiant le type! C'est l'une des propriétés les plus intéressantes des typeclasses de Haskell: le comportement de votre programme est déterminé par ses types.
Bien sûr, la plupart du temps, vous ne voyez pas ces types, car ils sont inférés. Par exemple, si vous écrivez le programme suivant, vous aurez pas besoin d'écrire des annotations de type:
ghci> id True
True
Même si la fonction id
est de type a -> a
, GHC peut en déduire qu'il n'y a manifestement que un choix pour a
, Bool
, donc il est choisi. Cependant, considérez votre programme - comment GHC peut-il savoir ce que doit être a
? Le résultat response
est utilisé que dans un seul endroit, getResponseStatusCode
, qui a la signature de type:
getResponseStatusCode :: Response a -> Int
Cette fonction fonctionne également sur touteResponse a
, donc GHC ne peut toujours pas décider ce que le a
devrait être: selon à la terminologie de GHC, la variable a
est ambiguë. Le problème est que choisir un type spécifique pour a
est nécessaire, car il doit savoir quelle instance FromJSON
utiliser pour analyser le corps de la réponse.
Pour résoudre ce problème, vous pouvez désambiguïser l'expression en fournissant votre propre annotation de type, ce qui oblige GHC à choisir un type particulier pour a
:
makeRequest = do
response <- httpJSON "http://httpbin.org/get" :: IO (Response())
putStrLn $ "The status code was: " ++ show (getResponseStatusCode response)
Bien sûr, vous devez remplacer ()
avec quel type représente la structure du JSON que vous attendez de la réponse.
Merci pour cette réponse incroyable. Cela fonctionne, et cela m'aide à comprendre pourquoi! – TomDane