Re: unification of array types
"Sebastien Mondet [email protected] [ocaml_beginners]" <[email protected]> Mon, 1 Aug 2016 16:47:22 -0400
| Newsgroups | gmane.comp.lang.ocaml.beginners |
|---|---|
| Message-ID | <CALScVY=oXZgZ-Dkwu7YMqJa0FY_wAEostf-NT8t6nHwtGH7CFg@mail.gmail.com> |
Hi
Your problem is with records not arrays :)
Tuples work because they are "structurally" typed. The records do not work
in your case because the field name `foo` is actually 2 completely
different field names `S1.foo` and `S2.foo` (I don't know your setup but
your code gives a bunch of warnings for me because of writing `{ foo = 1 }`
without the module name).
To reunify you can put your record type outside the functor:
module type MS = sig type t end;;
module M1 = struct type t = int end;;
module M2 = struct type t = int end;;
type 'a record = { foo : 'a }
module type S = sig module M : MS type a = M.t record end;;
module MAKE_S (M : MS) : S with module M = M = struct module M = M type a =
M.t record end;;
module S1 = MAKE_S(M1);;
module S2 = MAKE_S(M2);;
let a1 : S1.a = { foo = 1 };;
let a2 : S2.a = { foo = 2 };;
a1 == a2;;
→ this type checks
If that doesn't work for you, you can play with objects instead of records
(but it's syntactically heavy and error messages can get a bit violent...)
Cheers
Seb
On Mon, Aug 1, 2016 at 4:28 PM, [email protected] [ocaml_beginners] <
[email protected]> wrote:
> Let's define a few modules to play with functors:
>
> # module type MS = sig type t end;;
> module type MS = sig type t end
> # module M1 = struct type t = int end;;
> module M1 : sig type t = int end
> # module M2 = struct type t = int end;;
> module M2 : sig type t = int end
>
> The first functor build an array type:
>
> # module type S = sig module M : MS type a = { foo : M.t } end;;
> module type S = sig module M : MS type a = { foo : M.t; } end
> # module MAKE_S (M : MS) : S with module M = M = struct module M = M type
> a = { foo : M.t } end;;
> module MAKE_S :
> functor (M : MS) ->
> sig module M : sig type t = M.t end type a = { foo : M.t; } end
> # module S1 = MAKE_S(M1);;
> module S1 :
> sig
> module M : sig type t = M1.t end
> type a = MAKE_S(M1).a = { foo : M.t; }
> end
> # module S2 = MAKE_S(M2);;
> module S2 :
> sig
> module M : sig type t = M2.t end
> type a = MAKE_S(M2).a = { foo : M.t; }
> end
> # let a1 : S1.a = { foo = 1 };;
> val a1 : S1.a = {S1.foo = 1}
> # let a2 : S2.a = { foo = 2 };;
> val a2 : S2.a = {S2.foo = 2}
> # a1 == a2;;
> Error: This expression has type S2.a = MAKE_S(M2).a
> but an expression was expected of type S1.a = MAKE_S(M1).a
>
> So the compiler knows the types of the arrays, but seems to refuse to
> "unify" the field names.
> The same test with a tuple instead of an array works as expected:
>
> # module MAKE_S' (M : MS) : S' with module M = M = struct module M = M
> type a = M.t * float end;;
> module MAKE_S' :
> functor (M : MS) ->
> sig module M : sig type t = M.t end type a = M.t * float end
> # module S1' = MAKE_S'(M1);;
> module S1' : sig module M : sig type t = M1.t end type a = M.t * float end
> # module S2' = MAKE_S'(M2);;
> module S2' : sig module M : sig type t = M2.t end type a = M.t * float end
> # let a1 : S1'.a = 1,1.;;
> val a1 : S1'.a = (1, 1.)
> # let a2 : S2'.a = 1,1.;;
> val a2 : S2'.a = (1, 1.)
> # a1 == a2;;
> - : bool = false
>
> Is there anything that can be done to still use arrays in this situation?
>
>
>
> ------------------------------------
> Posted by: [email protected]
> ------------------------------------
>
> Archives up to December 31, 2011 are also downloadable at
> http://www.connettivo.net/cntprojects/ocaml_beginners
> The archives of the very official ocaml list (the seniors' one) can be
> found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
> ------------------------------------
>
> Yahoo Groups Links
>
>
>
>