I have a data with a few constructors:
我有几个构造函数的数据:
data MyData =
A1 { var1 :: Int, var2 :: String }
A2 { var1 :: Int, var2 :: String, var3 :: Char }
A3 { var1 :: Int, var2 :: Char, var3 :: String, var4 :: String }
This is a simplified version of my real "data". Without using deriving (Generic)
, how can I implement it for the class ToJSON
?
这是我真实“数据”的简化版本。不使用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?
1 个解决方案
#1
2
Aeson's Parser
is an instance of Alternative
. As such, you can provide multiple parsers and combine them with (<|>)
:
Aeson的Parser是Alternative的一个实例。因此,您可以提供多个解析器并将它们与(<|>)组合:
{-# 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"
Note that the order of parsers is important, since v .: "var1"
and v .: "var2"
succeed for all three parsers.
请注意,解析器的顺序很重要,因为v。:“var1”和v。:“var2”对所有三个解析器都成功。
#1
2
Aeson's Parser
is an instance of Alternative
. As such, you can provide multiple parsers and combine them with (<|>)
:
Aeson的Parser是Alternative的一个实例。因此,您可以提供多个解析器并将它们与(<|>)组合:
{-# 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"
Note that the order of parsers is important, since v .: "var1"
and v .: "var2"
succeed for all three parsers.
请注意,解析器的顺序很重要,因为v。:“var1”和v。:“var2”对所有三个解析器都成功。