# Combinator library for extracting data for s-exps?

**URL:** <https://discuss.ocaml.org/t/combinator-library-for-extracting-data-for-s-exps/10153>\
**Category:** Community\
**Created:** [July 10, 2022, 5:20am UTC](https://discuss.ocaml.org/t/combinator-library-for-extracting-data-for-s-exps/10153 "2022-07-10T05:20:03Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [July 10, 2022, 5:20am UTC](https://discuss.ocaml.org/t/combinator-library-for-extracting-data-for-s-exps/10153/1 "2022-07-10T05:20:03Z")

</div>

### Context

I want to write a simple script to consume some s-expressions output by `dune` and do something with them.

Input looks like this:

```auto
((executables
  ((names (main))
   (requires
    (2e58431e757317d4157ed69cdbce2cb0 c480a7c584d174c22d86dbdb79515d7d))
   (modules
    (((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 ()))))))
   (include_dirs (_build/default/src/bin/.main.eobjs/byte))))
  ...)

```

And I’d like to get the “name” and list of modules and their dependencies for each “executables” of the toplevel list.

### Question

Are there opam packages that offer small combinator libraries to write such code? I looked at the [Sexplib documentation](https://ocaml.org/p/sexplib/v0.15.0/doc/index.html) and I’m not under the impression that there is something there. (I think that it’s a rather basic question and it’s weird that the documentation does not answer it, but oh well.)

### What I found

Within Sexplib, there is:

- a [Conv](https://ocaml.org/p/sexplib/v0.15.0/doc/Sexplib/Conv/index.html) module that provides some `foo_of_sexp` conversions that could conceivably be used for this, but are more meant for one-to-one mapping to OCaml types. (Note: here I consider that the s-expression I get is random, and may not fit an OCaml type.)
- a [Grammar](https://ocaml.org/p/sexplib/v0.15.0/doc/Sexplib/Sexp_grammar/index.html) module that looks like a much-more-engineered version of what I would naively look for, and probably overkill for what I’m looking for. (Also, an example or two in the documentation would help, but oh well.)
- a [Path](https://ocaml.org/p/sexplib/v0.15.0/doc/Sexplib/Path/index.html) module that looks like it may contain nice ways to do selector-based data lookup in s-expressions but is in fact aimed at something else (substitutions)

### Home-grown example

I spent an hour writing something specific yesterday, writing combinators at the same time, and it looks like this. I’m not saying this is good (I’m sure it will look different next time I write it again), but it gives a rough idea of the sort of combinators I would have expected to find a library for.

```ocaml
let read_entries entries =
  let entries = list entries in
  let* (name, entry) =
    begin
      let+ exec = select_all ["executables"] entries in
      (select_single ["names"] exec |> list_of atom |> single,
       exec)
    end @ begin
      let+ lib = select_all ["library"] entries in
      (select_single ["name"] item |> atom,
       lib)
    end
  in
  let+ module_ = select_single ["modules"] item |> list_of list in
  let name = select_single ["name"] module_ |> atom in
  let impl = select_single ["impl"] module_ |> list |> single |> atom in
  let deps =
    let deps = select_single ["module_deps"] module_ |> list in
    (select_single ["for_intf"] deps |> list_of atom)
    @
    (select_single ["for_impl"] deps |> list_of atom)
  in
  (item_name, name, impl, deps)

```

### JSON

This looks like a problem common to other data forms, for example Json data. Curiously enough, I don’t remember looking for such a library to write with Json data in the past: I guess the fact that it is just slightly more structured (with explicit representation of lists and dictionaries) makes it easy to just use `List.assoc` directly.

---

_[View the full topic](https://discuss.ocaml.org/t/combinator-library-for-extracting-data-for-s-exps/10153)._
