Source

pa_ovisitor / pa / test / test_readme.ml

type t = 
  | Foo of int list 
  | Bar of int * int
with ovisit

class c = object
  inherit ovisit_t

  (* the state *)
  val mutable st = 0
  method st = st

  (* visitor *)
  method int n = st <- st + n
  method list = List.iter
end


let () = 
  let o1 = new c in
  o1#t (Foo [1;2;3;4;5]);
  assert (o1#st = 15);
  let o2 = new c in
  o2#t (Bar (1,2)); 
  assert (o2#st = 3)

type u = { t : t; children : u list } with ovisit

class c_u = object
  inherit c
  inherit ovisit_u
end

let () = 
  let o1 = new c_u in
  o1#u { t = Foo [1;2;3;4;5]; children = [] }; 
  assert (o1#st = 15);
  let o2 = new c_u in
  o2#u { t = Bar (1,2); 
         children = [ { t = Foo [1;2;3;4;5]; children = [] };
                      { t = Bar (3,4); children = [] } ]
       };
  assert (o2#st = 25)

module Fold = struct

  type t = 
    | Foo of int list 
    | Bar of int * int
  with ofold

  class c = object
    inherit [int] ofold_t
  
    method int st n = st + n
    method list = List.fold_left
  end

  let () = 
    let o = new c in (* folder is pure, so we only need one o *)
    assert ( o#t 0 (Foo [1;2;3;4;5]) = 15 );
    assert ( o#t 0 (Bar (1,2)) = 3 ) 

end

module Map = struct

  type t = 
    | Foo of u list 
    | Bar of int * int

  and u = { l : t list }
  with omap

  class c = object
    inherit [int] omap_t
  
    method int st n = (st + n), n+1
    method list f st xs = 
      List.fold_left (fun (st,xs) x -> 
        let st, x = f st x 
        in st, x::xs) 
        (st,[]) (List.rev xs)
  end

  let () = 
    let o = new c in (* folder is pure, so we only need one o *)
    assert ( o#t 0 (Foo [{l = [ Bar (1,2); Bar (3,4) ]}]) 
             = (10, Foo [{l = [ Bar (2,3); Bar (4,5)]}]) );
    assert ( o#t 0 (Bar (1,2)) = (3, Bar (2,3)) ) 

end