1

我在找什么

假设T为 OCaml 数据类型(例如:)type t = A | B of int,并x为 type 的值,是否存在满足以下要求T的函数:f

  1. f映射x到一个字符串,即f(x)是一个字符串表示x
  2. 对于所有u,vT,u = v当且仅当f(u) = f(v)
  3. f可以自动推导出来,比如type t = ... [@@deriving yojson]
  4. 一个相对简单类型的值的字符串表示,如上面定义的,应该是人类可编辑的
  5. (不是必需的,但很好)局部性,即如果将t上面的类型扩展为type t = A | B of int | C of something,则f("A the one before the extending")应该等于f("A the one after the extending"),换句话说,它应该使将旧版本的类型升级到新版本变得容易

为什么我想要这个

将 OCaml 数据存储到 Postgres 列中。我有一个使用 PGOCaml 从 Postgres 获取数据的小型 Web 应用程序,并且 PGOCaml 类型在编译时检查 SQL 语句,所以如果你create domain some_type as text在 Postgres 中,并稍微更改 PGOCaml 的源代码(使用上面f的转换 Postgrestext到 OCaml 类型),您可以将 ADT 存储到 Postgres 表中,同时保持类型安全。

要求中的第二点很重要,因为在 Postgres 方面,您可能需要测试该列的相等性,并且此类测试是在 Postgrestext类型上完成的。

我查看了 Sexp,没有找到关于第二点的信息。

PS,刚接触OCaml,这种东西是不是已经有成熟的解决方案了?

更新

我最终使用了 yojson,因为我的类型非常简单,只是零变量,我可以摆脱它,虽然它是一个远离完美的星系。

更新 2

对于那些有类似问题的人,我认为当前最好的解决方案是使用 yojson,而不是将其存储在text列中,将其存储在 a 中jsonb,这样,您可以获得空格和顺序不敏感的比较,(虽然我找不到pg 的关于jsonb类型相等性的文档)。

4

1 回答 1

0

将 RichouHunters 评论升级为回答者,因为我认为 Sexplib 是一个很好的模块:

我认为 s 表达式可能(或可能不)满足您的第二个要求的方式很大程度上取决于您的类型 T 和定义序列化程序的方式。您将在此处找到有关它们(和 Sexplib)的更多信息。

于 2018-04-17T10:20:01.143 回答