我的程序依赖于一个库,该库将我提供的JSON解码为其内部数据类型。
库试图封装太多内容。它隐藏了连接细节、数据序列化格式和后台使用的RPC,因此使用起来很方便。
问题是库拒绝了我必须在环境中处理的JSON。换句话说,它拒绝处理JSON有效负载的常见错误,如大小写差异、意外但无害的密钥、可恢复的Number/String编码错误。
我不能依赖newtype
技巧,因为库希望使用具体的数据类型,而不是我的。我需要更改它用于反序列化的"内部"类实例。
由于没有更好的想法,我分叉了这个库,并将其添加为从本地目录构建的依赖项(还必须删除所有与stack
相关的内容,这样构建才会引起注意(。
数据类型没有改变,只更改了序列化格式,使此更改与手头的问题无关。
有没有更好的方法来覆盖库提供的类实例定义?
我已经遇到过几次类似的问题,这很烦人。如果你还没有考虑的话,可以考虑一些选项:
-
我们可以希望该库提供Haskell组合子来构建内部类型。然后,您可以包装类型并提供一个替代
FromJSON
实例:newtype WrappedT = WrappedT { toT :: Library.T } deriving (All, The, Classes, You, Care, About) instance FromJSON WrappedT where -- better instance
-
对JSON进行预规范化,也就是说,将JSON写入JSON层,以删除不可接受的位。
- 如果您不想维护fork,请向作者推送一份PR,公开
.Internal
模块中的内部内容,然后您就可以执行解决方案1。这将保持兼容性,同时仍然允许您进行更改。(我个人也认为这样的"软封装"比更常见的"刚性封装"对社区更好(
如果你提供了问题的更多细节,你可能会想到其他解决方案。