2017-10-11 5 views
2

この機能は動作します:なぜhttpJSONは失敗しますが、httpLBSは成功しますか? (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. 

答えて

9

は、の種類を比較httpLBSおよびhttpJSON

常にResponse ByteStringを生成するが、 httpLBSResponse aを生成すること

は注意してください。どういう意味ですか?この場合

、それはhttpJSONFromJSONインスタンスがすべてで何かを含むResponseを作り出すことができることを意味し、それが決定する関数の呼び出し側次第です。発信者はどのように決定しますか?タイプを指定することにより!これは、Haskellのtypeclassesのもっとも興味深いプロパティの1つです。プログラムの動作は、タイプによって決まります。

もちろん、ほとんどの場合、推論されているので、これらのタイプは表示されません。あなたは、以下のプログラムを作成する場合たとえば、あなたはどのタイプの注釈を記述する必要はありません。

ghci> id True 
True 

id機能がa -> a型を持つにもかかわらず、GHCはaのためだけ1つの選択肢が明確にあることを推測することができます、Boolですので、選択されています。しかし、あなたのプログラムを考えてみてください.GHCはどうすればaが何になっているのかを知ることができますか? GHCはまだaがどうあるべきかを決定することはできませんので

getResponseStatusCode :: Response a -> Int 

この機能はまた、任意のResponse aに動作します:response結果は、以下のタイプの署名を持っている一つの場所、getResponseStatusCode、で使用されるに従って、 GHCの用語によれば、a変数はであいまいですです。問題は、回答ボディを解析するために使用するインスタンスを知る必要があるため、aの特定のタイプを選択する必要があるということです。もちろん

makeRequest = do 
    response <- httpJSON "http://httpbin.org/get" :: IO (Response()) 
    putStrLn $ "The status code was: " ++ show (getResponseStatusCode response) 

、あなたはどんなタイプの()を交換する必要があります。この問題を解決するために、あなたはaのための特定のタイプを選択するGHCを強制的に、あなた自身の型注釈を供給することにより、表現を明確にすることができて

応答が生成することを期待するJSONの構造を表します。

+0

このようなすばらしい答えをありがとう。それは動作し、それはなぜ私が理解するのに役立ちます! – TomDane

関連する問題