struct

  include Map.Make(String)

  let singleton key data =
    add key data empty

  exception Strict of string

  let strict_add key data m =
    try
      let _ = find key m in
      raise (Strict key)
    with Not_found ->
      add key data m

  let union m1 m2 =
    fold add m1 m2

  let strict_union m1 m2 =
    fold strict_add m1 m2

  let domain m = 
    fold (fun k _ acu -> StringSet.add k acu) m StringSet.empty 

end