vegetus
vegetus

Reputation: 95

OCaml: type incompatibilities between sets

I'm having troubles with type incompatibilities in OCaml.

First, I have a file setBuilder.ml where I define a functor SO that creates an order for sets, a functor S that creates sets, and a functor SM that creates a module containing useful functions to work with sets:

module SO (M: sig type t end)
  = struct
    type t = M.t
    let compare = Pervasives.compare
  end

module S (P: sig type t end): Set.S with type elt = P.t
  = Set.Make (SO (P))

module SM (M: sig type t end): 
sig
  type t = M.t
  module S: Set.S with type elt = t
  type set = S.t
  ...
end
= struct
  module S = S (M)
  ...
end

(In such a situation I'm used to combining such 3 modules into 1 recursive module, but it appears that OCaml doesn't let you create recursive modules when a parameter is excepted (i.e., when it's a functor)).

Then in a different file, called module_U.ml, I define a module U where the function foo will be important:

module U (M: sig type t end):
sig
  module S : Set.S with type elt = M.t
  type elt = M.t
  type eltSet = S.t
  val foo: eltSet -> eltSet -> bool
end
= struct 
  module S = S (M)
  let foo s1 s2 = 
  ...
end

And in my main.ml, I finally define a module containing the type I'll be using,

module T : 
sig 
  type t=int
end 
= struct 
  type t=int
end 

then I instantiate the module SM and obtain its set S:

module SM = SM (T)  
module IntSet = SM.S 

Then I instantiate the module U and attempt to use its function foo:

module U = U (T)
let bar (s1:IntSet.t) (s2:IntSet.t) : bool = 
  U.foo s1 s2

But I get the error message

File "main.ml", line 303, characters 38-39  (which corresponds to s1, in U.foo s1 s2):
Error: This expression has type IntSet.t = setBuilder.SM(T).S.t
       but an expression was expected of type
         U.eltSet = module_U.U(T).S.t

What I don't understand, is why this is a problem, since both U and SM modules are created with the same module T, meaning that the type of the two sets created should be the same.

If anyone can provide any thoughts on this I'll be thankful.

Upvotes: 2

Views: 230

Answers (1)

user2299816
user2299816

Reputation:

Try using module S : module type of S(M), or alternatively module S : Set.S with type elt = M.t and type t = S(M).t. The problem with module S : Set.S with type elt = M.t is that it doesn't constrain the type S.t

Upvotes: 2

Related Questions