首页 > 解决方案 > Thoth.Json.Net – 解码器作为函子,有可能吗?

问题描述

我为 F# 找到了这个出色的 JSON 库,它的灵感来自 Elm 的 Json.Decode,它定义了一个Decoder像这样的基本类型:

type Decoder<'T> = string -> obj -> Result<'T, DecoderError> (这里)

有像Decode.map这样的函数,我希望我可以使它与 F#+ 兼容,所以我可以像这样使用它:

let customerId = Decode.string |>> CustomerId (见|>>通用映射的中缀版本)

据我所知,要使第 3 方库使用诸如 Functors 之类的 F#+ 概念,需要使用 扩展第 3 方类型static member Map,但这Decoder<'T>只是一个缩写。

有什么解决办法吗?有人试过吗?

PS到目前为止,我的解决方案是自定义绑定:

let (<!>) = Decode.map
let customerId: Decoder<CustomerId> = CustomerId <!> Decode.string
let submitId: Decoder<SubmitId> = SubmitId <!> Decode.string
let currency: Decoder<Currency> = Currency <!> Decode.string
// etc…

标签: f#f#+

解决方案


问题是您无法控制代码。如果您可以控制它,则解决方案是:

  • 实现Decoder为具体类型,而不是类型别名。类型别名不能有额外的成员,因为它不是真正的另一种类型。库作者应该使用区分大小写的联合,因为您可以使它们成为几乎零开销的结构。

  • 添加Map具有所需签名的成员。

或者,如果扩展成员在未来的 F# 版本中对特征约束变得可见,您将能够仅使用 Map 函数扩展类型,可能会产生一些不希望的效果,因为它是具有 2 个参数的函数的类型别名。

所以,我认为你能做的最好的就是你已经展示的东西。

附带说明一下,您可能有兴趣查看Fleece,它也提供解码器,但它也更进一步,为您提供双向的编解码器(您可以在map<*>之上)。


推荐阅读