Partial decoding
(I am creating an issue for the second part of my feedback at https://discuss.ocaml.org/t/combinator-library-for-extracting-data-for-s-exps/10153/7 )
I'm trying to parse only some parts of the data, not decode all of it into an isomorphic representation. In particular, I have a key-value s-expression and I want to get the fields foo
and bar
, in any order, ignoring the other fields. I did not find a way to do this using the current Sexp_decode API, which seeems designed to fetch all fields at one. I wrote the following
let module_decoder entry_name =
let+ name = field "name" atom
and+ impl = field "impl" (list1 atom) |> map List.hd
and+ deps = field "module_deps" deps_decoder
in (name, impl, deps)
and I was expecting to run against data as in my example:
((name Main)
(impl (_build/default/src/bin/main.ml))
(intf ())
(cmt (_build/default/src/bin/.main.eobjs/byte/dune__exe__Main.cmt))
(cmti ())
(module_deps ((for_intf ()) (for_impl ()))))))
but, re-reading the documentation, my usage of field can only works if there is no data to ignore in-between, and I list the fields exactly in order. I don't want to do that. I could use the record combinator but then I would have to list all possible fields I think, and I don't want to / cannot do that. (I'm only observing one run of the data producer, there may be other fields that will show up with other options or as the producer changes.)
If I understand correctly, the underlying mental model of Sexp_decode
is to consume input in the order of the decoders in the code. For partial decoding, I'm rather looking for the ability to call several partial decoders on a given input, without consuming input. The only combinators that allow this in the current API are meant for backtracking: you can call several decoders on the same input (first
, or_else
), but only in the case where one decoder fails.