The following code fails to compile:
module Foo = struct
module St = struct type t = string let compare = compare end
module Map (* : Map.S with type key = St.t *)
= Map.Make(St)
(* module Map = Map.Make(struct type t = string let compare = compare end) *)
end
module Bar = struct
type t = int Foo.Map.t
end
module Pack = struct
module Foo = Foo
module Bar = Bar
end
open Pack
let x : Bar.t = Foo.Map.empty
----
File "
foo.ml", line 20, characters 16-29: (* refers to Foo.Map.empty on last line *)
Error: This expression has type
but an expression was expected of type
Pack.Bar.t = int Map.Make(Foo.St).t
So Pack.Foo and Foo are not compatible. By trial and error, I found two ways to resolve the problem:
1) Provide an explicit signature for Foo.Map (uncomment the provided signature), or
2) Inline the structure passed to Map.Make (comment out first definition of Foo.Map and uncomment the second one)
But I don't understand why. Can anyone explain the main points. Thank you.