I just wrote a parser for my input data using Decoders_sexplib, and the result works. It’s the only library recommended in the thread that solves my specific problem, so far.
open Decoders_sexplib.Decode
let module_deps_decoder =
let+ for_intf = field "for_intf" (list string)
and+ for_impl = field "for_impl" (list string)
in for_intf @ for_impl
let module_decoder entry_name =
let+ name = field "name" string
and+ impl = field "impl" (list string) |> map List.hd
and+ deps = field "module_deps" module_deps_decoder
in (entry_name, name, impl, deps)
let exec_decoder =
let* entry_name = field "names" (list string) |> map List.hd in
field "modules" (list (module_decoder entry_name))
let lib_decoder =
let* entry_name = field "name" string in
field "modules" (list (module_decoder entry_name))
let entry_decoder =
list_filter (
string |> uncons @@ fun kind ->
match kind with
| "executables" -> let+ v = list exec_decoder in Some v
| "library" -> let+ v = list lib_decoder in Some v
| _ -> succeed None
)
|> map List.flatten
|> map List.flatten
Note that entry_decoder
is an example of a decoder working on a sum type / variant as you mention:
- in this example I use
list_filter
to only handle the variantsexecutable
andlibrary
and ignore the others - there is an extra level of
list
wrapping (andList.flatten
in the result), due to I think the inner working of the Decoders library which was designed with JSON rather than s-exprs in mind. I’m not sure but I think that it normalizes(polyline foo bar)
into something like(polyline (foo bar))
.