Source

pa_ovisitor / pa / test / test_readme.ml

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

and u = { l : s list }

and s = t list
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 [{l = [[ Bar (1,2); Bar (3,4) ]]}]);
  assert (o1#st = 10);
  let o2 = new c in
  o2#t (Bar (1,2)); 
  assert (o2#st = 3)

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

class c_v = object
  inherit c
  inherit ovisit_v
end

let () = 
  let o1 = new c_v in
  o1#v { t = Foo [{l = [[ Bar (1,2); Bar (3,4) ]]}]; children = [] }; 
  assert (o1#st = 10);
  let o2 = new c_v in
  o2#v { t = Bar (1,2); 
         children = [ { t = Foo [{l = [[ Bar (1,2); Bar (3,4) ]]}]; children = [] };
                      { t = Bar (3,4); children = [] } ]
       };
  assert (o2#st = 17)

module Fold = struct

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

  and u = { l : s list }

  and s = t list
  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 [{l = [[ Bar (1,2); Bar (3,4) ]]}]) = 10 );
    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 : s list }

  and s = 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