package ppx_traverse

  1. Overview
  2. Docs
Automatic generation of open-recursion classes


Dune Dependency






Ppx\_traverse is a ppx_type_conv plugin generating open recursion classes from type definition.

Published: 15 Dec 2017


#+TITLE: ppx-traverse
#+PARENT: ../

Ppx\_traverse is a [[][ppx_type_conv]] plugin generating open recursion
classes from type definition. Users can overwrite a specific method of
the generated classes in order to specialize the recursion on specific
nodes. Ppx\_traverse is in particular used to generate the open
recursion classes to traverse the OCaml AST in [[][ppx_core]].

For instance, this is the kind of code generated (the generated code
is between the =[@@deriving_inline ...]= and =[@@@end]=):

#+begin_src ocaml
type expression =
  | Var   of string
  | Const of int
  | Add   of expression * expression
  | If    of cond * expression * expression

and cond =
  | Cond_var   of string
  | Cond_const of bool
  | Cond_and   of cond * cond

[@@deriving_inline traverse_map]
class map = object(self)
  method virtual int    : int    -> int
  method virtual string : string -> string
  method virtual int    : int    -> int

  method expression = function
    | Var x -> Var (self#string x)
    | Const x -> Const (self#int x)
    | Add (x, y) -> Add (self#expression x, self#expression y)
    | If (x, y, z) -> If (self#cond x, self#expression y, self#expression z)

  method cond = function
    | Cond_var x -> Cond_var (self#string x)
    | Cond_const x -> Cond_const (self#bool x)
    | Cond_and (x, y) -> Cond_and (self#cond x, self#cond y)

Now if you wanted to do a deep-copy of an expression, replacing
boolean variable =foo= by =true=:

#+begin_src ocaml
let replace_var = object
  inherit map as super

  method cond = function
    | Cond_var "foo" -> Cond_const true
    | c -> super#cond c

let replace_var expr = replace_var replace_var#expression expr
#+end_src contains the definition for all the
builtin types, such as =int=, =string=, =list=, ... This module is
distributed in a separate [[][ppx_traverse_bultins]] package to break a
circular dependency between Ppx\_core and Ppx\_traverse.

** Classes

Ppx\_traverse can generate the following classes: =map=, =iter=,
=fold=, =fold_map=, =map_with_context=, =lift=. =[@@deriving
traverse]= is an alias to generate all the supported classes.

=lift= is a special class that is mostly useful to lift an OCaml
constant to the AST that represent this constant. To do so, you can
use =ppx_metaquot.lifters= from [[][ppx_metaquot]]:

#+begin_src ocaml
type t = { x : int; y : int } [@@deriving traverse_lift]

let expression_of_t ~loc t : Ast.expression =
  let lift = object
    inherit Ppx_metaquot_lifters.expression_lifters loc
    inherit lift
  end in
  lift#t t

Dependencies (7)

  1. ocaml-migrate-parsetree >= "0.4" & < "2.0.0"
  2. jbuilder >= "1.0+beta12"
  3. ppx_type_conv >= "v0.10" & < "v0.11"
  4. ppx_metaquot >= "v0.10" & < "v0.11"
  5. ppx_driver >= "v0.10" & < "v0.11"
  6. ppx_core >= "v0.10" & < "v0.11"
  7. ocaml >= "4.04.1"

Dev Dependencies


Used by (2)

  1. ppx_custom_printf = "v0.10.0"
  2. ppx_expect >= "v0.10.0" & < "v0.11.0"