Question

I'm using Aeson for some client-server stuff that I'm doing, encoding ADTs as Json. I'm using Data.Aeson.TH to generate the toJSON instances I need, but the instances generated for Map types are really ugly and awful to deal with.

I've defined my own, simpler encoding which just treats them as lists:

instance (ToJSON a, ToJSON b) => ToJSON (Map a b) where
  toJSON m = toJSON $ toList m

Naturally, when I use this in my code, I get a Duplicate instance declarations error.

Is there a way to resolve this? I need to either tell Template Haskell NOT to generate the ToJson instance for Map, or I need to tell GHC to ignore that instance and use the one I supply. Can either of these be done?

Note that this isn't an "overlapping-instances" problem. I want to completely throw out the one instance, not mix it with the other one.

Was it helpful?

Solution

To tell GHC to ignore library-provided instance and use your own instead, you can wrap Map in a newtype:

newtype PrettyMap key val = PrettyMap (Map key val)
instance (ToJSON a, ToJSON b) => ToJSON (PrettyMap a b) where
  toJSON (PrettyMap m) = toJSON $ toList m

Another solution is to really use OverlappingInstances:

data MyData = ...
$(deriveToJSON ... ''MyData)

instance ToJSON (Map Text MyData) where
    toJSON = toJSON . toList
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top