2016-04-17 54 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

這不是一個有效的'數據'類型。你錯過了一些'|'? – Zeta

+0

你問ToJSON,然後顯示FromJSON ...你想要嗎? –

回答

2

埃宋的ParserAlternative一個實例。因此,您可以提供多個解析器和與(<|>)將它們結合起來:

{-# 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" 

注意解析器的順序很重要,因爲v .: "var1"v .: "var2"所有三個解析器成功。

相關問題