json - 使用 Aeson/JSON 处理派生的 Aeson FromJSON 实例中的 `id`

标签 json haskell generics aeson custom-data-type

如果我有 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
  ]
}

代码到目前为止:
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

这给出了错误:
[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.

理想情况下,我想更改第一个 idbody_id第二个到 taxCode_id无需写出整个实例。

最佳答案

派生 FromJSON 实例时,您可以将选项传递给 genericParseJSON功能。通常是

data Foo = {- ... -} deriving (Show, Generic)

instance FromJSON Foo where
    parseJSON = genericParseJSON defaultOptions
    -- defaultOptions :: Options

而你可以替换defaultOptionsOption您手动构建。 Option类型有一个字段 fieldLabelModifier可以预处理您的数据类型的字段名称。您可以将数据类型定义为
data Body = Body
  { body_id :: Int
  ...

并编写一个映射 "body_id" 的辅助函数至"id"以及其他任何未更改的内容:
body_noprefix "body_id" = "id"
body_noprefix s = s

然后将实例定义为
instance FromJSON Body where
  parseJSON = genericParseJSON (defaultOptions { fieldLabelModifier = body_noprefix })

关于json - 使用 Aeson/JSON 处理派生的 Aeson FromJSON 实例中的 `id`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35702440/

相关文章:

javascript - 如何从 Json 字符串中删除转义字符?

haskell - 使用 makeTokenParser 定义词法分析器时类型推断失败

java - 如何修复 "unchecked call to ' AttachView(V )' as a member of raw type ' BasePresenter'"?

json - EXTJS 3.4 将 JSON 数据动态加载到树中

javascript - X2JS删除属性前缀

haskell - 约束种类: Pass multiple constraints

haskell - Haskell 的 'seq' 与其他函数有何不同?

c# - 我如何在内部保留泛型类型参数的始终可为 null 的等价物?

c# - 如何使用 Unity 将通用接口(interface)自动注册到该接口(interface)的非通用实现

c# - 首先使用 C# Json.NET 反序列化具有变量名的 Json 数组