Thoth.Json.Net – 解码为 Functor,可能吗?

Thoth.Json.Net – Decoder as a Functor, is it possible?

我发现 this 极好的 F# JSON 库,它的灵感来自 Elm 的 Json.Decode,它定义了一个基本的 Decoder 类型,如下所示:

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

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

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

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

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

P.S。 到目前为止,我的解决方案是自定义绑定:

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…

问题是您无法控制代码。如果你能控制它,一个解决方案是:

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

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

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

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

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