重写Haskell中封装不好的实例



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

库试图封装太多内容。它隐藏了连接细节、数据序列化格式和后台使用的RPC,因此使用起来很方便。

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

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

由于没有更好的想法,我分叉了这个库,并将其添加为从本地目录构建的依赖项(还必须删除所有与stack相关的内容,这样构建才会引起注意(。

数据类型没有改变,只更改了序列化格式,使此更改与手头的问题无关。

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

我已经遇到过几次类似的问题,这很烦人。如果你还没有考虑的话,可以考虑一些选项:

  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. 如果您不想维护fork,请向作者推送一份PR,公开.Internal模块中的内部内容,然后您就可以执行解决方案1。这将保持兼容性,同时仍然允许您进行更改。(我个人也认为这样的"软封装"比更常见的"刚性封装"对社区更好(

如果你提供了问题的更多细节,你可能会想到其他解决方案。

最新更新