Mapping Keys
OCaml's standard library provides maps and sets, implemented using
module functors. To use a map, we create a module for the type we
want to use as keys via Map.Make; for a set, we create a module
for the type of its elements via Set.Make. For this problem,
assume we're given the following three modules.
module StringMap : Map.S with type key = string module IntMap : Map.S with type key = int module StringSet : Set.S with type elt = string
StringMap and IntMap are maps with string and int keys,
respectively, and StringSet is a set of string values. Each
supports the usual Map.S and Set.S operations, e.g.,
StringMap.add, StringMap.find, StringMap.bindings,
StringSet.add, StringSet.elements, and so on.
Implement the function
val flip_keys_and_values : int StringMap.t -> StringSet.t IntMap.t
so that flip_keys_and_values m is the map m' gotten by making
the values of m into keys. The value associated with a key v in
m' is the set of keys in m that map to the value v.
Examples
Since StringMap.t and IntMap.t values aren't directly comparable
with = in a way that reflects their bindings, we compare using
IntMap.equal (and StringSet.equal) instead.
let m = StringMap.of_seq (List.to_seq [("a", 1); ("b", 2); ("c", 1); ("d", 3)]) let out = flip_keys_and_values m let expected = IntMap.of_seq (List.to_seq [(1, StringSet.of_list ["a"; "c"]); (2, StringSet.of_list ["b"]); (3, StringSet.of_list ["d"])]) let _ = assert (IntMap.equal StringSet.equal out expected) let _ = assert (IntMap.equal StringSet.equal (flip_keys_and_values StringMap.empty) IntMap.empty)