4

私が見たすべての例は、次のように、単一のコンストラクターを持つデータ型を対象ToJSONとしています。FromJSON

data RewindConfig = RConfig JobID Phase
                      deriving Show

instance FromJSON RewindConfig where
  parseJSON (Object o) = RConfig
    <$> o .: "JobID"
    <*> o .: "Phase"
  parseJSON _ = fail "invalid RewindConfig"

Aesonが複数のコンストラクターを持つ型のインスタンスをどのように作成するかを調べてみようと思いました。たとえば、次のようになりますEither

instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
   parseJSON (Object (H.toList -> [(key, value)]))
        | key == left  = Left  <$> parseJSON value
        | key == right = Right <$> parseJSON value
   parseJSON _        = fail ""

parseJSONのパターンマッチングは私を混乱させます、私は何が起こっているのか理解していません(H.toList -> [(key, value)])

インスタンスを作成するデータ型は次のようになります。

data Foo = Bar String
         | Baz String
         | Bin String

実装方法を知っている何かをすることが私に起こりました

data Foo = (Maybe Bar) (Maybe Baz) (Maybe Bin)

しかし、それは満足のいくものではないようです。誰かがEitherインスタンスで何が起こっているのかを説明し、おそらくTo / Fromインスタンスに関するガイダンスを教えてくれますFooか?

更新:Aesonが実装するインスタンスMaybeははるかに明確であり、自分のニーズのために何を知る必要があるかを教えてくれると思います。それでも、で何が起こっているのか知りたいEitherです。

4

3 に答える 3

4

このパターンをビューパターン(Object (H.toList -> [(key, value)]))と呼びます。次のように読むことができます。

parseJSon (Object o) = case H.toList o of
    [(key, value)]
        | key == left  -> Left  <$> parseJSON value
        | key == right -> Right <$> parseJSON value

上記は常にパターンObject oにコミットするため、実際にはわずかに異なりObjectます.かまいません。Object oH.toList o[(key, value)]

于 2012-04-26T18:55:00.157 に答える
2

json パッケージには、採用する可能性のあるデータ型のエンコーディングが含まれています。派生するだけなら、Dataそれを使用できます。それほど高速ではありませんが、非常に使いやすいです。

于 2012-04-26T18:50:45.177 に答える