Hi,
Peng Zang < peng.zang%40gmail.com">peng.zang
gmail.com> writes:
> (* test one, same modules as argument *)
> module A = Bar (Foo);;
> module B = Bar (Foo);;
> A.barprint B.barval;;
>
> (* test two, same modules but named differently *)
> module X = Bar (Foo1);;
> module Y = Bar (Foo2);;
> X.barprint Y.barval;;
>
> -------- end snip ---------
This is not about funtor.
<code>
# #tell "X.t";;
type X.t = Bar(Foo1).t = { randstring : string; thefooval : Foo1.t; }
# #tell "Y.t";;
type Y.t = Bar(Foo2).t = { randstring : string; thefooval : Foo2.t; }
</code>
X.t and Y.t are not compatible because record fields are already bounded module
name:
<code>
# X.barval;;
- : X.t = {X.randstring = "hi"; X.thefooval = 2}
# Y.barval;;
- : Y.t = {Y.randstring = "hi"; Y.thefooval = 2}
</code>
Note the "X" and "Y" prefix to the fields. How could you expect a value with
field "X.thefooval" and another value with field "Y.thefooval" compatible?
Without funtor, you can have the same problem:
<code>
# module A = struct type t = {a:int} let x = {a=1} end;;
module A : sig type t = { a : int; } val x : t end
# module B = struct type t = {a:int} let x = {a=2} end;;
module B : sig type t = { a : int; } val x : t end
# A.x;;
- : A.t = {A.a = 1}
# [A.x; B.x];;
Characters 6-9:
[A.x; B.x];;
^^^
This expression has type B.t but is here used with type A.t
</code>
So records are nominally typed. But their fields don't have to
<code>
# [X.barval.X.thefooval; Y.barval.Y.thefooval];;
- : Foo1.t list = [2; 2]
</code>
If you want structural compatibility between types, then use structurally typed
types such as tuple:
<code>
module Bar (Foo : FOO) = struct
type t = string * Foo.t
let barprint t =
Format.printf "%s, " (fst t); Foo.fooprint (snd t)
let barval = ("hi", Foo.fooval)
end;;
module X = Bar(Foo1);;
module Y = Bar(Foo2);;
# X.barprint Y.barval;;
hi, 2- : unit = ()
# [X.barval; Y.barval];;
- : (string * Foo1.t) list = [("hi", 2); ("hi", 2)]
</code>
HTH.