The function visit_type visit all nodes of a type that are not marked to be excluded and has not yet been visited and applying a function f to each visited none.
let visit_type exclude visited f t = let rec visit t = let t = repr t in if t.mark = exclude || t.mark == visited then () else begin t.mark <- visited; f t; match desc t with | Tvar _ -> () | Tcon (g, l) -> List.iter visit l end in visit t;;
The generalization mark variables that are free in the environment, then list variables in the type that are noted mark as free in the environment.
let generalizable tenv t0 = let inenv = marker() in let mark m t = (repr t).mark <- m in let visit_asumption (x, (q, t)) = let bound = marker() in List.iter (mark bound) q; visit_type bound inenv ignore t in List.iter visit_asumption tenv; let ftv = ref [] in let collect t = match desc t with Tvar _ -> ftv := t::!ftv | _ -> () in let free = marker() in visit_type inenv free collect t0; !ftv;; let x = tvar();; generalizable [] (tarrow x x);;