let rec fold_types f gen x tm = match tm.term with
| Unit | Bool _ | Int _ | String _ | Float _ | Encoder _ | Var _ ->
f gen x tm.t
| List l ->
List.fold_left (fun x tm -> fold_types f gen x tm) (f gen x tm.t) l
| Ref r | Get r ->
fold_types f gen x r
| Product (a,b) | Seq (a,b) | Set (a,b) ->
fold_types f gen (fold_types f gen x a) b
| App (tm,l) ->
let x = fold_types f gen x tm in
List.fold_left (fun x (_,tm) -> fold_types f gen x tm) x l
| Fun (_,p,v) ->
fold_types f gen
(List.fold_left
(fun x -> function
| (_,_,t,Some tm) ->
fold_types f gen (f gen x t) tm
| (_,_,t,None) ->
f gen x t)
x
p)
v
| Let {gen=gen';def=def;body=body} ->
let x = fold_types f (gen'@gen) x def in
fold_types f gen x body