GHCJSiバージョン0.2.0-7.10.3:http://www.github.com/ghcjs/ghcjs/とhttps://github.com/reflex-frp/reflex-domからreflex-domライブラリバージョン0-4を使用しています。私はHackageからreflex-dom-0.3を使用していません。ハスケル:どのように "型変数のあいまいな"コンパイラエラーを修正するには?
次Haskellのプログラムは反射-DOM-0.4でコンパイルされません。
{-# LANGUAGE RecursiveDo, ScopedTypeVariables, DeriveGeneric, OverloadedStrings #-}
import Reflex
import Reflex.Dom
import Data.Aeson
import GHC.Generics
import qualified Data.Text as T
data Apod = Apod { copyright :: T.Text
, date :: T.Text
, explanation :: T.Text
, hdurl :: T.Text
, media_type :: T.Text
, service_version :: T.Text
, title :: T.Text
, url :: T.Text
} deriving (Generic, Show)
instance FromJSON Apod
main :: IO()
main = do
mainWidget $ el "div" $ do
buttonEvent <- button "GET"
let url = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"
let defaultReq = xhrRequest "GET" url def
asyncEvent <- performRequestAsync (tag (constant defaultReq) buttonEvent)
let rspApod = fmapMaybe (\r -> decodeXhrResponse r) asyncEvent
return()
私は反射-DOMライブラリ関数decodeXhrResponse
(ともdecodeText
)をインラインエラーに
Xhr00.hs:24:36:
No instance for (aeson-0.9.0.1:Data.Aeson.Types.Class.FromJSON b0)
arising from a use of ‘decodeXhrResponse’
The type variable ‘b0’ is ambiguous
Relevant bindings include
rspApod :: Event Spider b0 (bound at Xhr00.hs:24:9)
Note: there is a potential instance available:
instance (aeson-0.9.0.1:Data.Aeson.Types.Class.FromJSON a,
aeson-0.9.0.1:Data.Aeson.Types.Class.FromJSON b) =>
aeson-0.9.0.1:Data.Aeson.Types.Class.FromJSON
(Data.These.These a b)
-- Defined in ‘Data.These’
In the expression: decodeXhrResponse r
In the first argument of ‘fmapMaybe’, namely
‘(\ r -> decodeXhrResponse r)’
In the expression:
fmapMaybe (\ r -> decodeXhrResponse r) asyncEvent
Failed, modules loaded: none.
を取得。私は、型名FromJSON a => XhrResponse -> Maybe a
を型変数XhrResponse -> Maybe Apod
のない署名に変更します。その後、プログラムは正常にコンパイルされます。
{-# LANGUAGE RecursiveDo, ScopedTypeVariables, DeriveGeneric, OverloadedStrings #-}
import Reflex
import Reflex.Dom hiding (decodeXhrResponse, decodeText)
-- import Reflex.Dom
import Data.Aeson
import GHC.Generics
import qualified Data.Text as T
import Control.Monad
import qualified Data.ByteString.Lazy as BL
import Data.Text.Encoding
data Apod = Apod { copyright :: T.Text
, date :: T.Text
, explanation :: T.Text
, hdurl :: T.Text
, media_type :: T.Text
, service_version :: T.Text
, title :: T.Text
, url :: T.Text
} deriving (Generic, Show)
instance FromJSON Apod
main :: IO()
main = do
mainWidget $ el "div" $ do
buttonEvent <- button "GET"
let nasa = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"
let defaultReq = xhrRequest "GET" nasa def
asyncEvent <- performRequestAsync (tag (constant defaultReq) buttonEvent)
let rspApod :: Event Spider Apod = fmapMaybe (\r -> decodeXhrResponse r) asyncEvent
return()
-- Inlined and changed library function:
-- decodeXhrResponse :: FromJSON a => XhrResponse -> Maybe a
decodeXhrResponse :: XhrResponse -> Maybe Apod
decodeXhrResponse = join . fmap decodeText . _xhrResponse_responseText
-- Inlined and changed library function:
-- decodeText :: FromJSON a => T.Text -> Maybe a
decodeText :: T.Text -> Maybe Apod
decodeText = decode . BL.fromStrict . encodeUtf8
私はrspApod :: Event t Apod
またはrspApod :: Event Spider Apod
ようrspApod用スコープ型変数を追加しようとしましたが、それは助けにはなりませんでした。
質問:
はどうすれば正常にコンパイルする最初のプログラムを変更する必要がありますか?
なぜ、コンパイラはApod
データ型のFromJSON
インスタンスを見つけて使用しないのですか?いいえ、ライブラリの機能を変更することは非常に悪いハックです。
'(\ r - > decodeXhrResponse r)'〜> 'decodeXhrResponse' –
元のプログラムはあいまいです。型シグネチャ 'decodeXhrResponse r :: Maybe Apod'を追加するだけですか? –
@Reid:ありがとうございますが、 'let rspApod = fmapMaybe(\ r - > decodeXhrResponse r :: Maybe Apod)asyncEvent'に変更しても問題は解決しません。同じ' No instance for'エラーが返されます。残念ながら... – Jogger