type expr =
  | EConst of int
  | EAdd of expr * expr
  [@@deriving visitors { variety = "iter" }]

let weight (e : expr) : int =
(* return the weight of an expr, where the weight of constants is its *)
(* value, and additions have weight 5.                                *)
  let v = object
    val mutable weight = 0
    method weight = weight
    inherit [_] iter as super
    method! visit_EAdd env e0 e1 =
      weight <- weight + 5;
      super#visit_EAdd env e0 e1
    method! visit_EConst env i =
      weight <- weight + i;
      super#visit_EConst env i
    end in
  v#visit_expr () e;
  v#weight
;;

let c = EConst 2 in
    let e = EAdd(c,EAdd(c,c)) in
    print_int (weight e)
;;
