module type S = sig
type msg
val dispatch : msg -> unit
end
module A : S = struct
type msg
let dispatch _ = ()
end
module B = struct
type msg
module C = (A : S with type msg = msg)
end
This results in an error:
module C = (A : S with type msg = msg)
^
Error: Signature mismatch:
Modules do not match:
sig type msg = A.msg val dispatch : msg -> unit end
is not included in
sig type msg = msg val dispatch : msg -> unit end
Type declarations do not match:
type msg = A.msg
is not included in
type msg = msg
The type msg/1 is not equal to the type msg/2
What does this error mean? Why can’t the two abstract types get unified?
module A : S = struct
type msg
...
end
module B = struct
type msg
...
end
creates two fresh and unrelated types named msg (or more precisely A.msg and B.msg) .
Those types are distinct and it would be a mistake to consider them equal.
The problem I’m trying to solve is that type msg will be provided by the user of the library, and since the library code cannot refer to the user modules unless I add functors to the api, I was hoping that there is a way to use sharing constraints to relate the msg type in all library modules. Maybe you can suggest strategies for dealing with this problem other than using functors?
If the type is provided by the user, you cannot define it yourself. Depending on the level of polymorphism needed, you can use either define functions on record of functions (or objects), or move to functors.
For instance,
type msg = { dispatch: unit -> unit }
let do_something {dispatch} = dispatch ()