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:
f
mapsx
to a string, i.e.f(x)
is a string representation ofx
- for all
u
,v
inT
,u = v
if and only iff(u) = f(v)
f
can be derived automatically, liketype t = ... [@@deriving yojson]
- the string representation of a value of a relatively simple type, like the one defined above, should be human editable
- (not essential, but nice to have) locality, i.e., if you extend the type
t
above totype t = A | B of int | C of something
, thenf("A the one before the extending")
should be equal tof("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).
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.