忽略/覆盖使用TemplateHaskell生成的实例

时间:2014-02-17 00:38:53

标签: haskell ghc typeclass template-haskell aeson

我正在使用Aeson来处理我正在做的一些客户端服务器,将ADT编码为Json。我正在使用Data.Aeson.TH来生成我需要的toJSON个实例,但是为Map类型生成的实例真的很丑陋且难以处理。

我已经定义了我自己的,更简单的编码,只将它们视为列表:

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

当然,当我在我的代码中使用它时,我收到Duplicate instance declarations错误。

有没有办法解决这个问题?我需要告诉Template Haskell不为Map生成ToJson实例,或者我需要告诉GHC忽略该实例并使用我提供的实例。可以这样做吗?

请注意,这不是“重叠实例”问题。我想完全抛弃一个实例,而不是将它与另一个实例混合。

1 个答案:

答案 0 :(得分:4)

要告诉GHC忽略库提供的实例并使用您自己的实例,您可以将Map包装为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

另一个解决方案是真正使用OverlappingInstances

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

instance ToJSON (Map Text MyData) where
    toJSON = toJSON . toList