(* TEST *) module IntMap = Map.Make(struct type t = int let compare x y = x-y end) let m1 = IntMap.add 0 "A" (IntMap.add 4 "Y" (IntMap.singleton 3 "X1")) let m2 = IntMap.add 0 "B" (IntMap.add 4 "Y" (IntMap.singleton 5 "X2")) let show m = IntMap.iter (fun k v -> Printf.printf "%d %s\n" k v) m let () = print_endline "Union+concat"; let f1 _ l r = match l, r with | Some x, None | None, Some x -> Some x | Some x, Some y when x = y -> None | Some x, Some y -> Some (x ^ y) | _ -> assert false in show (IntMap.merge f1 m1 m2); print_endline "Inter"; let f2 _ l r = match l, r with | Some x, Some y when x = y -> Some x | _ -> None in show (IntMap.merge f2 m1 m2); print_endline "Union+concat (with Map.union)"; let f3 _ l r = if l = r then None else Some (l ^ r) in show (IntMap.union f3 m1 m2); () let show m = IntMap.iter (fun k v -> Printf.printf "%d -> %d\n" k v) m let update x f m = let yp = IntMap.find_opt x m in let y = f yp in match yp, y with | _, None -> IntMap.remove x m | None, Some z -> IntMap.add x z m | Some zp, Some z -> if zp == z then m else IntMap.add x z m let () = print_endline "Update"; let rec init m = function | -1 -> m | n -> init (IntMap.add n n m) (n - 1) in let n = 9 in let m = init IntMap.empty n in for i = 0 to n + 1 do for j = 0 to n + 1 do List.iter (function (k, f) -> let m1 = update i f m in let m2 = IntMap.update i f m in if not (IntMap.equal ( = ) m1 m2 && ((m1 == m) = (m2 == m))) then begin Printf.printf "ERROR: %s: %d -> %d\n" k i j; print_endline "expected result:"; show m1; print_endline "result:"; show m2; end ) [ "replace", (function None -> None | Some _ -> Some j); "delete if exists, bind otherwise", (function None -> Some j | Some _ -> None); "delete", (function None -> None | Some _ -> None); "insert", (function None -> Some j | Some _ -> Some j); ] done; done; ;;