type ('a, 'r, 'z) wt = '-> ('-> 'z) -> 'z

let with_identity r f = f r
  
let with_alt with1 with2 (a, b) f' =
  let ok1 = ref false
  in
    try with1 a (fun r1 -> let () = ok1 := true in f' (None, r1))
    with
    | e1 -> if !ok1 then raise e1 else with2 b (fun r2 -> f' ((Some e1), r2))
  
let with_uncurry3 f3 (a, b, c) = f3 a b c