The type si solution is what I am using of now, but I was wondering if there is anyway of having the whole module. To get the compile-time errors that I mentioned in my original post, one would have to do something like:
# module S = MyMap (String) ;;
# type t_si = int S.t ;;
# let si : t_si = S.add_exn S.empty ~key:"0" ~data:0 ;;
# let si' : t_si = S.add_exn S.empty ~key:"0" ~data:"zero" ;; (* compiler error *)
Notice the explicit type annotations, without which there would be no compiler error since empty itself is polymorphic.
No, there is no way to fix the data type, short of defining a signature like so:
module type Map_with_fixed_data = sig
...
val filter_map : t -> f:('a -> 'a option) -> t
end
where you basically fix each type yourself. I still don’t see why you’d really want this, though. The compiler will warn you if you try to use a map with the wrong data type later on, no? Can you provide a concrete use-case?
You are correct. When I use the actual Map.t values with the wrong type, I would get a compilation error. This was purely out of curiosity.
Thinking more about it, I agree with you that a polymorphic internal type for the module is totally fine. Even for modules like List, we don’t need to specialize the to IntList modules for operating on the int list type.