1

我想生成代表 AST 的 JSON 对象,我正在考虑ppx_deriving_yojson这样做(更具体地说是to_yojson部分)。现在,当我想求助于自定义编码时,当然有一些极端情况。如文档中所述,自定义记录字段的表示很容易:

type bar = { test: int;
             test1: int [@to_yojson fun i -> `String (string_of_int i)] }
[@@deriving to_yojson]

let j1 = bar_to_yojson { test = 0; test1 = 1 }

会给我

val j1 : Yojson.Safe.t = `Assoc [("test", `Int 0); ("test1", `String "1")]

但是有些地方我想为 sum 类型的变体提供自定义表示,并且to_yojson此处似乎无法识别该属性:

type foo = Bar | Bla of string [@to_yojson fun s -> `String (s ^ "_suffix")]
[@@deriving to_yojson]

let j2 = foo_to_yojson (Bla "bla")

给我

val j2 : Yojson.Safe.t = `List [`String "Bla"; `String "bla"]

即默认编码ppx_deriving_yojson。我是否缺少某些东西,或者根本无法实现我想要的东西?

注意:结果是使用utop#require "ppx_deriving_yojson";;作为第一个命令获得的

4

1 回答 1

0

我忘记了内联记录。这将大致做我想要的:

type foo = Bar | Bla of { bla: string [@to_yojson fun s -> `String (s ^ "_suffix")]}
[@@deriving to_yojson]

let j2 = foo_to_yojson (Bla { bla = "bla"})

val j2 : Yojson.Safe.t =
  `List [`String "Bla"; `Assoc [("bla", `String "bla_suffix")]]

然而,虽然这个解决方案适用于全新的开发,但它意味着对现有类型的重大重构工作。因此,我仍在寻找侵入性较小的解决方案。

于 2020-03-18T07:24:01.713 回答