package ppx_traverse

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

Install

Dune Dependency

Authors

Maintainers

Sources

ppx_traverse-v0.9.0.tar.gz
sha256=beb90a43431e147dbdd842262b08099ba2b7db3e1488afe6a7e91f0a9e59b6bb
md5=9031e3649e21c9e0f3e58f4470b14c29

README.org.html

README.org

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

Ppx\_traverse is a [[https://github.com/janestreet/ppx_type_conv][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 generatd the open
recursion classes to traverse the OCaml AST in [[https://github.com/janestreet/ppx_core][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 conditional * expression * expression

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

[@@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)
[@@end]
#+end_src

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 Ppx_traverse_builtins.map
  inherit map as super

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

let replace_var expr = replace_var replace_var#expression expr
#+end_src

=Ppx_traverse_builtins.map= contains the definition for all the
builtin types, such as =int=, =string=, =list=, ... This module is
distributed in a separate [[https://github.com/janestreet/ppx_traverse_bultins][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 [[https://github.com/janestreet/ppx_metaquot][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
#+end_src
OCaml

Innovation. Community. Security.