2016-04-17 9 views
0

私はいくつかのコンストラクタを使用してデータを持っている:自分のデータ型にFromJSONを正しく実装するにはどうすればいいですか?

data MyData = 
    A1 { var1 :: Int, var2 :: String } 
    A2 { var1 :: Int, var2 :: String, var3 :: Char } 
    A3 { var1 :: Int, var2 :: Char, var3 :: String, var4 :: String } 

これが私の本当の「データ」の簡易版です。 deriving (Generic)を使用しないと、クラスToJSONのためにどのように実装できますか?

instance FromJSON MyData where 
    parseJSON (Object v) = do 
    .. --- how do I know if v is created by A1 or A2 or A3? 
+0

これは有効な 'data'型ではありません。 '|'をいくつか見逃しましたか? – Zeta

+0

あなたはToJSONについて質問してからFromSson ...を表示したいですか? –

答えて

2

アイソーンのParserAlternativeのインスタンスです。そのように、あなたは複数のパーサを提供することができ、(<|>)と組み合わせる:v .: "var1"v .: "var2"は、3つのすべてのパーサーのために成功したので、パーサの順序は、重要であること

{-# LANGUAGE OverloadedStrings #-} 
import Control.Applicative ((<|>)) 
import Data.Aeson 

-- Removed record fields to keep things short, but you can put them back. 
data MyData = A1 Int String 
      | A2 Int String Char 
      | A3 Int Char String String 
      deriving Show 

instance FromJSON MyData where 
    parseJSON (Object v) = A3 <$> v .: "var1" <*> v .: "var2" <*> v .: "var3" <*> v .: "var4" 
         <|> A2 <$> v .: "var1" <*> v .: "var2" <*> v .: "var3" 
         <|> A1 <$> v .: "var1" <*> v .: "var2" 

注意を。

関連する問題