I have the following modules/functors:
module Number = struct
module type S = sig
type t
(* ... *)
end
module OrderedVector (Num : S) = struct
type t = Num.t Iarray.t
let rec compare (a : t) (b : t) : int =
(* ... *)
end
module Q : S with type t = Q.t = Q (* From [zarith] package. *)
end
module Polytope = struct
module Make (Num : Number.S) : sig
val h_to_v :
(* ... *) ->
Set.Make(Number.OrderedVector(Num)).t
end
end
And a test case where I do the following:
module LinalgQ = Linalg.Make (Number.Q)
module PolytopeQ = Polytope.Make (Number.Q)
module VectorQ = Number.OrderedVector (Number.Q)
module VectorSetQ = Set.Make (VectorQ)
(* Tests follow here. *)
I got the following error:
173 | (PolytopeQ.h_to_v ~simplify:false);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type
Number.Q.t Polytope.constr list ->
Number.Q.t Polytope.constr list ->
Set.Make(MyProject.Number.OrderedVector(MyProject.Number.Q)).t
but an expression was expected of type
Number.Q.t Polytope.constr list ->
Number.Q.t Polytope.constr list -> VectorSetQ.t
Type
Set.Make(MyProject.Number.OrderedVector(MyProject.Number.Q)).t
is not compatible with type VectorSetQ.t
But when I make the following change, it works:
module LinalgQ = Linalg.Make (Number.Q)
module PolytopeQ = Polytope.Make (Number.Q)
module VectorQ = Number.OrderedVector (Number.Q)
-module VectorSetQ = Set.Make (VectorQ)
+module VectorSetQ = Set.Make (Number.OrderedVector (Number.Q))
Note that I simply replaced VectorQ with Number.OrderedVector (Number.Q), which is how I defined VectorQ. Now my code compiles. Why?
I tried to find a simple example to reproduce this behavior, but the following code compiles too:
module type T = sig
type t
end
module M = struct
type t = int
end
module F (A : T) = struct
type t = A.t
end
module G (B : T) = struct
type t = B.t
end
module F0 = F (M)
module G1 = G (F0)
module G2 = G (F (M))
type t0 = F0.t
type t1 = G1.t
type t2 = G2.t
let foo01 : t0 -> t1 = fun x -> x
let foo02 : t0 -> t2 = fun x -> x
let foo12 : t1 -> t2 = fun x -> x
So how exactly are the following lines different:
module VectorQ = Number.OrderedVector (Number.Q)
module VectorSetQ = Set.Make (VectorQ)
versus
module VectorQ = Number.OrderedVector (Number.Q)
module VectorSetQ = Set.Make (Number.OrderedVector (Number.Q))
I would assume they both should be the same, right? But they are not.
Any help is appreciated.
I assume it must have to do with me using VectorQ in my test.
let testable_qvec =
Alcotest.testable
(fun ppf vec -> Format.pp_print_array Q.pp_print ppf (Iarray.to_array vec))
(Iarray.for_all2 Q.equal)
let testable_qvecset = Alcotest.slist testable_qvec VectorQ.compare
let testable_qvecset_triple =
let x = testable_qvecset in
Alcotest.triple x x x
And then later:
let verify (name : string) func =
let vertices = VectorSetQ.to_list @@ func basis_equations constraints in
Alcotest.check testable_qvecset name expected_vertices vertices
in
verify "Vertices equal to expectation when using h_to_v without simplify."
(PolytopeQ.h_to_v ~simplify:false);
But still, isn’t a module instantiated twice with the same functor argument exactly the same module?