OCaml: serialize data into string with additional requirements

378 views Asked by At

what I am looking for

Let T be an OCaml data type, (example: type t = A | B of int), and x be a value of type T, is there a function f that satisfies the following requirements:

  1. f maps x to a string, i.e. f(x) is a string representation of x
  2. for all u, v in T, u = v if and only if f(u) = f(v)
  3. f can be derived automatically, like type t = ... [@@deriving yojson]
  4. the string representation of a value of a relatively simple type, like the one defined above, should be human editable
  5. (not essential, but nice to have) locality, i.e., if you extend the type t above to type t = A | B of int | C of something, then f("A the one before the extending") should be equal to f("A the one after the extending"), in another word, it should make upgrading an old version of a type to the new version easy

why I want this

Store an OCaml data into Postgres column. I have a small web app that uses PGOCaml to fetch data from Postgres, and PGOCaml type checks the SQL statement at compile time, so if you create domain some_type as text in Postgres, and change the source code of PGOCaml a bit (to use the above f to convert a Postgres text into an OCaml type), you can store ADT into a Postgres table, while maintain type safety.

The second point in the requirements is important, for on the Postgres side, you likely need to test for equality on that column, and such tests are done on Postgres text type.

I looked into Sexp, didn't find information about the second point.

PS, new to OCaml, does this kind of thing already have a mature solution?

Update

I end up using yojson, since my type is very simple, just nullary variants, I can get away with it, it's a galaxy away from perfect though.

Update 2

For those who has the similar problem, I think the current best solution is to use yojson, and instead of storing it in a text column, storing it in a jsonb, this way, you get white space and order insensitive comparison, (though I cannot find pg's documentation on the equality of jsonb type).

1

There are 1 answers

0
Goswin von Brederlow On

Upgrading RichouHunters comment to an answere as I think Sexplib is a good module for this:

I think the way s-expressions may (or may not) satisfy your second requirement will depend a lot on your type T and on the way you define the serializer. You'll find more about them (and Sexplib) here.