覆盖Haskell中封装不良的实例

时间:2018-12-12 18:51:02

标签: haskell

我的程序依赖于一个将我提供的JSON解码为其内部数据类型的库。

该库试图封装太多。它隐藏了连接详细信息,数据序列化格式和内部使用的RPC,因此易于使用。

问题是该库拒绝了我必须在我的环境中处理的JSON。换句话说,它拒绝处理JSON有效负载的常见错误,例如大写/小写差异,意外但无害的键,可恢复的Number / String编码错误。

我不能依靠newtype技巧,因为该库希望使用具体的数据类型,而不是我的。我需要更改用于反序列化的“内部”类实例。

我没有一个更好的主意,我将该库进行了分叉,并补充说,它是从本地目录构建的依赖项(还必须删除与stack相关的所有内容,以便构建能够引起注意)。

数据类型保持不变,仅更改了序列化格式,从而使此更改可以解决手头的问题。

是否有更好的方法来覆盖库提供的类实例定义?

1 个答案:

答案 0 :(得分:3)

我几次遇到类似的问题,这很烦人。如果您还没有考虑,可以考虑以下一些选择:

  1. 我们希望该库提供Haskell组合器来构建内部类型。然后,您可以包装类型并提供其他FromJSON实例:

    newtype WrappedT = WrappedT { toT :: Library.T }
        deriving (All, The, Classes, You, Care, About)
    
    instance FromJSON WrappedT where
        -- better instance
    
  2. 对JSON进行预规范化,即编写一个JSON到JSON层,以删除不可接受的位。

  3. 如果您不想维护分支,则将PR推给作者,以在.Internal模块中公开内部,那么您可以执行解决方案1。这将在保持兼容性的同时仍允许您进行更改。 (我个人还认为,像这样的“软封装”比更常见的“刚性封装”更适合社区使用)

如果您提供问题的更多详细信息,可能还会想到其他解决方案。