2

Question

Is there a way to create a record with a field called "data"?

data MyRecord =
  MyRecord {
    otherField :: String,
    data       :: String  -- compilation error
  }

Why do I need it?

I've been writing a wrapper around a JSON API using Aeson and the remote service decided to call one of the fields data.

{
  pagination: {
    ..
  },
  data: [ 
    { .. },
    { .. },
  ]
}
LA.27
  • 1,888
  • 19
  • 35
  • Does this answer your question? [How to deal with Haskell's reserved keywords in record fields?](https://stackoverflow.com/questions/48474587/how-to-deal-with-haskells-reserved-keywords-in-record-fields) – n. m. could be an AI Nov 26 '22 at 21:24

1 Answers1

4

Yes, you can name the field something else than data, like:

data MyRecord =
  MyRecord {
    otherField :: String,
    recordData :: String
  }

And then derive a ToJSON with a key modifier:

labelMapping :: String -> String
labelMapping "recordData" = "data"
labelMapping x = x

instance ToJSON MyRecord where
    toJSON = genericToJSON defaultOptions {
            fieldLabelModifier = labelMapping
        }

instance FromJSON Coord where
    parseJSON = genericParseJSON defaultOptions {
            fieldLabelModifier = labelMapping
        }
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • I guess that for `FromJSON` I need to provide an inverted mapping, right? – LA.27 Nov 26 '22 at 21:38
  • 2
    @AlojzyLeszcz: no, if I recall correctly you can use the same `Options` object. It will exhaustively enumerate over the fields. – Willem Van Onsem Nov 26 '22 at 21:39
  • aeson sort of pushes you into this solution, but I'm uneasy with it because it's extremely "stringly typed". If you change the name of your field and forget to change the label mapping, your `FromJSON` instance is broken. I would manually write the parser instead. – danidiaz Nov 27 '22 at 08:27