How can sexplib be used with functor types like Map?

Sexplib syntax extension simplifies serialization and deserialization of custom user data structures in OCaml. This is usually done by adding the annotation with sexp to the end of the type definition:

 type a = A of int | B of float with sexp 

This is not like generalizing directly to functor-based types, and it’s not clear how even standard functors can capture Sexplib standard type converters.

So far I have been working on this, smoothing out a specific instance of a map type (e.g. int Map.Make(String).t ) before the list before serializing and vice versa, but, of course, this was not completely missed by the ambitious Sexplib / Jane Street authors at all Core. I also notice that older versions of Batteries mix in the custom serialization of sexp with their core modules such as [Bat] Map, but that it has been removed for some time.

What are Maps or other complex types of functors commonly used with Sexplib serialization?

+6
source share
1 answer

One way is to define a new functor that accepts the additional information needed to serialize the data. Here's the full implementation I've used in the past with Batteries. Note. I also preferred the exclusive and flagged version of the map, so I opened it, but of course you can delete it.

 module type SEXPABLE = sig type t val sexp_of_t : t -> Sexplib.Sexp.t val t_of_sexp : Sexplib.Sexp.t -> t end module Map = struct module type S = sig include BatMap.S include module type of Labels include module type of Exceptionless val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'at -> Sexplib.Sexp.t val t_of_sexp : (Sexplib.Sexp.t -> 'a) -> Sexplib.Sexp.t -> 'at end module Make (Ord : BatInterfaces.OrderedType) (Sexpable : SEXPABLE with type t = Ord.t) : S with type key = Ord.t = struct include BatMap.Make(Ord) include Labels include Exceptionless open Sexplib.Sexp open Sexplib.Conv let sexp_of_t sexp_of_data t = let f ~key ~data ans = List [Sexpable.sexp_of_t key; sexp_of_data data] :: ans in List (fold ~f ~init:[] t) let t_of_sexp data_of_sexp sexp = match sexp with | Atom _ -> of_sexp_error "Map.Make(...).t_of_sexp: list needed" sexp | List l -> let f ans = function | List [key_sexp; data_sexp] -> let key = Sexpable.t_of_sexp key_sexp in let data = data_of_sexp data_sexp in add ~key ~data ans | List _ | Atom _ -> of_sexp_error "Map.Make(...).t_of_sexp: 2-tuple list needed" sexp in List.fold_left ~f ~init:empty l end end 

If I remember correctly, Batteries removed such functions in order to reduce dependency on additional libraries. Another option is to use Core, which has these features out of the box.

+1
source

Source: https://habr.com/ru/post/927513/


All Articles