今天我想解决下一个问题。
假设我们将 typeclassDataWithDefault
定义为
class DataWithDefault a where
defaultValue :: a
我们将数据Example
定义为
data Example =
Example { field1 :: Text
, field2 :: Text
} deriving (Show)
instance DataWithDefault Example where
defaultValue = Example "Hello" "World"
instance FromJSON Example where
parseJSON (Object v) =
Example <$> v .:? "field1" .!= field1 defaultValue
<*> v .:? "field2" .!= field2 defaultValue
parseJSON _ = mzero
instance ToJSON Example where
toJSON (Example f1 f2) =
object [ "field1" .= f1
, "field2" .= f2
]
我知道 Aeson 使用泛型自动派生FromJSON
和ToJSON
实例,但我不知道如何让它派生FromJSON
具有给定 json 中未表示的字段的默认值的实例。可以使用泛型吗?其实我没有问你最终的解决方案,但也许有一些线索?
更新
让我添加有关该问题的更多信息。
现在假设您需要更新Example
数据,现在它定义为
data Example =
Example { field1 :: Text
, field2 :: Text
, field3 :: Int
} deriving (Show)
所以你想更新DataWithDefault
实例声明
instance DataWithDefault Example where
defaultValue = Example "Hello" "World" 12
而我想做的不是写
instance FromJSON Example where
parseJSON (Object v) =
Example <$> v .:? "field1" .!= field1 defaultValue
<*> v .:? "field2" .!= field2 defaultValue
<*> v .:? "field3" .!= field3 defaultValue
parseJSON _ = mzero
并想自动导出这样的实例定义。更重要的是,我想这样做不仅是为了Example
,而是为了DataWithDefault a
。
更新 2
合并.:?
的.!=
目的是从给定的 json 中获取尽可能多的字段,并将每个缺失的字段设置为其默认值。所以当我们通过
{ "field1" : "space", "field2" : "ship" }
我希望我的新示例不是field1 = Hello; field2 = World; field3 = 12
,而是field1 = space; field2 = ship; field3 = 12
。