を得るこれは、現在の状態で自分のコード
--{-# LANGUAGE FlexibleInstances #-}
--{-# LANGUAGE MultiParamTypeClasses #-}
--{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
data Typed = Typed {typeID::Int,name::String} deriving (Show,Eq)
data Day = Day {orderCount::Int,lowPrice::Float,highPrice::Float, avgPrice:: Float,volume::Int,date::String}
data Order = Order {price::Float,isBuy::Bool,location::Typed} deriving (Show,Eq)
data Market a = Market {items::a,pageCount::Int,totalCount::Int} deriving (Show,Eq)
-- Can be either Market [Order] or Market [Day]
instance FromJSON (Market a) where
parseJSON (Object x) = Market <$> x .: "items" <*> x .: "pageCount" <*> x .: "totalCount"
instance FromJSON Order where
parseJSON (Object x) = Order <$> x .: "price" <*> x .: "buy" <*> x .: "location"
instance FromJSON Typed where
parseJSON (Object x) = Typed <$> x .: "id" <*> x .: "name"
instance FromJSON Day where
parseJSON (Object x) = Day <$> x .: "orderCount" <*> x .: "lowPrice" <*> x .: "highPrice"
<*> x .: "avgPrice" <*> x .: "volume" <*> x .: "date"
であり、これは現在のエラーです。最初はコンパイルエラーです:Market a
のインスタンスがあると主張すると、市場のJSONシリアライズをa
という任意の選択肢で解析する方法を知っているはずですが、これは実際には何かを解析したいので不可能ですprice
フィールドのコンテンツの価格を入力するにはa
と入力してください。
instance FromJSON a => FromJSON (Market a) where
...
を、今、すべてが順調です:
は、私たちは私達が私達のインスタンス宣言に制約を加えることで解析する方法を知っている可能a
年代を考慮に私達の注意を制限します。しかし、もう一つの問題があります。私たちはFromJSON
を実装しましたが、それは非網羅的なマッチでいっぱいです!これを-Wall
で実行して、GHCが私たちに不平を言うのを見てください。問題は、Object
以外のものが入力された場合、各parseJSON
は実際には例外で失敗します(解析の失敗ではなく、 "プログラム全体を爆破する"という失敗)。これは、我々が悪い振る舞いをすることを意味します。
λ> decode "1.0" :: Maybe Typed
*** Exception: /home/jozefg/scratch/Aeson.hs:(24,3)-(25,39): Non-exhaustive patterns in function parseJSON
これを修正するために、他のすべてのケースで明示的に失敗する別の句を追加することができます。より生産性の高いソリューションは、これらのインスタンスをすべて手書きしないことがあるかもしれません。なぜなら、それらはすべてかなり簡単で、代わりにaesonのジェネリックのサポートを使用するからです。ここで私はちょうど
instance FromJSON Order where
parseJSON (Object x) =
Order <$> x .: "price" <*> x .: "buy" <*> x .: "location"
parseJSON _ = mempty
が、それはあなたを伝えるものを、コンテキストに 'FromJSONをA'追加してください余分な句を追加しました。例えば
Order
ための固定インスタンスです:'インスタンスFromJSON A => FromJSONは(市場A) ... ' – user2407038ありがとうございます。私はそれが意味することを知らなかったし、それは簡単ではないと思った。これは、インスタンスを使用する私の最初の試みです、そして、私はちょうどそのインスタンスに関連するいくつかの "型が一致しませんでした"エラーを取り除いたので、それはそれより複雑であると思った。 –