Disambiguate the .= operator in Aeson in Haskell

时间:2019-04-17 01:39:26

标签: haskell aeson

I am trying to rename keys when serializing an object to json.

I understand the way to do that is to, rather than just using deriving generic, define an instance with custom key names like so:

-- instance ToJSON R2  -- old
instance ToJSON R2 where
  toJSON (R2 recCode recDate) = object [ "code" .= recCode , "date" .= recDate ]
-- new

However, this gives me:

<interactive>:2:70: error:
    Ambiguous occurrence ‘.=’
    It could refer to either ‘Data.Aeson..=’, imported from ‘Data.Aeson’ (and originally defined in ‘aeson-1.3.1.1:Data.Aeson.Types.ToJSON’)
                          or ‘Control.Lens..=’, imported from ‘Control.Lens’ (and originally defined in ‘Control.Lens.Setter’)

My attempt to fix this was to explicitly force the meaning of the .= operator by defining it in my code, eg:

(.=) = Data.Aeson.(.=)

This was a guess, but seems like the wrong syntax. I added the parens by analogy to the following resources:

This gave me this error:

(.=) = Data.Aeson (.=)

<interactive>:1:8: error:
    Not in scope: data constructor ‘Data.Aeson’
    No module named ‘Data’ is imported.

What is the correct syntax to say, "let .= be unambiguously the .= from Data.Aeson" ?

2 个答案:

答案 0 :(得分:7)

If you're OK with defining .= in your file to be the one from Aeson, you can simply hide the import of .= from Control.Lens:

import Control.Lens hiding ((.=))

Outer brackets are the import hiding list, inner brackets required due to .= being an operator - that is, having a name with non-alphanumeric characters.

答案 1 :(得分:2)

The answer can be found by reading the error output more carefully to see two periods, and surrounding the (whole thing) with parens as an operator. This works

(.=) = (Data.Aeson..=)