mat*_*ias 6 generics json haskell custom-data-type aeson
如果我有,JSON并且我尝试FromJSON自动派生实例Generics,我遇到问题,id存在于多个地方JSON.
有没有办法让我只覆盖id部分或者我必须编写整个实例才能更改这些特定的条目?在JSON实际上有更多的领域,但我最左侧的它在这个例子.因此,写出整个FromJSON实例实际上是相当繁琐的.
JSON:
{
"response": [
{
"id": 1,
"brandId": 1,
"productTypeId": 1,
"identity": {
"sku": "x",
"barcode": "Ax"
},
"stock": {
"stockTracked": false,
"weight": {
"magnitude": 0
},
"dimensions": {
"length": 0,
"height": 0,
"width": 0,
"volume": 0
}
},
"financialDetails": {
"taxable": false,
"taxCode": {
"id": 1,
"code": "x"
}
},
... etc
]
}
Run Code Online (Sandbox Code Playgroud)
代码到目前为止:
data Response = Response
{ response :: [Body]
} deriving (Show,Generic)
data Body = Body
{ id :: Int
, brandId :: Int
, productTypeId :: Int
, identity :: Identity
, productGroupId :: Int
, stock :: Stock
, financialDetails :: FinancialDetails
} deriving (Show,Generic)
data Identity = Identity
{ sku :: String
, ean :: String
, barcode :: String
} deriving (Show,Generic)
data Stock = Stock
{ stockTracked :: Bool
, weight :: Weight
, dimensions :: Dimensions
} deriving (Show,Generic)
data Weight = Weight
{ magnitude :: Int
} deriving (Show,Generic)
data Dimensions = Dimensions
{ length :: Int
, height :: Int
, width :: Int
, volume :: Int
} deriving (Show,Generic)
data FinancialDetails = FinancialDetails
{ taxable :: Bool
, taxCode :: TaxCode
} deriving (Show,Generic)
data TaxCode = TaxCode
{ id :: Int
, code :: String
} deriving (Show,Generic)
instance FromJSON Response
instance FromJSON Body
instance FromJSON Identity
instance FromJSON Stock
instance FromJSON Weight
instance FromJSON Dimensions
instance FromJSON FinancialDetails
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
[1 of 1] Compiling Main ( reponse.hs, interpreted )
response.hs:73:8:
Multiple declarations of `id'
Declared at: response.hs:19:7
response.hs:73:8
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想改变第一id到body_id,第二次taxCode_id,而无需编写出整个实例.
zak*_*aps 11
在派生FromJSON实例时,您可以将选项传递给该genericParseJSON函数.这通常是
data Foo = {- ... -} deriving (Show, Generic)
instance FromJSON Foo where
parseJSON = genericParseJSON defaultOptions
-- defaultOptions :: Options
Run Code Online (Sandbox Code Playgroud)
虽然你可以defaultOptions用Option你手工构造的替换.该Option类型具有fieldLabelModifier可以预处理数据类型的字段名称的字段.您可以将数据类型定义为
data Body = Body
{ body_id :: Int
...
Run Code Online (Sandbox Code Playgroud)
并编写一个辅助函数,映射"body_id"到"id"和其他任何不变的:
body_noprefix "body_id" = "id"
body_noprefix s = s
Run Code Online (Sandbox Code Playgroud)
然后将实例定义为
instance FromJSON Body where
parseJSON = genericParseJSON (defaultOptions { fieldLabelModifier = body_noprefix })
Run Code Online (Sandbox Code Playgroud)