0

私は GHCJSi のバージョン 0.2.0-7.10.3 を使用しています: http://www.github.com/ghcjs/ghcjs/およびhttps://github.com/reflex-の reflex-dom ライブラリ バージョン 0-4 frp/reflex-dom . Hackage の reflex-dom-0.3 は使用していません。

次の Haskell プログラムは、reflex-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 ()

エラーが発生します

 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.

reflex-dom ライブラリ関数decodeXhrResponse(および もdecodeText) をインライン化します。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 Apodor のような rspApod のスコープ型変数を追加しようとしました rspApod :: Event Spider Apodが、役に立ちませんでした。

質問:

正常にコンパイルするには、最初のプログラムをどのように変更する必要がありますか? (ライブラリ関数のインライン化と変更は非常に悪いハックです!)

FromJSONコンパイラがデータ型のインスタンスを見つけて使用しないのはなぜApodですか?

4

1 に答える 1