From: Oleg <oleg@okmij.org>
To: caml-list@inria.fr
Subject: [Caml-list] Are record types generative?
Date: Tue, 23 Jan 2018 23:54:53 +0900 [thread overview]
Message-ID: <20180123145453.GA1916@Magus.localnet> (raw)
I have recently received a rather odd type error:
Type declarations do not match:
type t = D.Product.t = { pid : int; name : string; price : int; }
is not included in
type t = RProduct.t = { pid : int; name : string; price : int; }
Apparently, two structurally identical record types are not regarded
equal (OCaml 4.04.0). The original code is a bit complicated, so
let me illustrate the problem on a simple example:
module type m1 = sig
type t = int
val v : t
end
module M1 : m1 = struct
type t = int
let v = 1
end
module F1(S:m1) = struct
let res = S.v = M1.v
end
let _ = let module M = F1(M1) in M.res;;
This code is accepted with no problems and gives the expected result
(1 is indeed equal to 1). Module M1 was checked to satisfy the
signature m1; therefore, S.v and M1.v should have the type int and be
the same.
Let's change the example slightly
module type m2 = sig
type t = {l:int}
val v : t
end
module M2 : m2 = struct
type t = {l:int}
let v = {l=1}
end
module F2(S:m2) = struct
let res = S.v = M2.v
end
Characters 43-47:
let res = S.v = M2.v
^^^^
Error: This expression has type M2.t but an expression was expected of type
S.t
Although both M2 and S are two instances of m2, and hence both
S.v and M2.v should have the record type t = {l:int}, they are not
regarded equal.
The problem is easy to fix:
module F3(S:m2 with type t = M2.t) = struct
let res = S.v = M2.v
end
;;
module F3 :
functor (S : sig type t = M2.t = { l : int; } val v : t end) ->
sig val res : bool end
let _ = let module M = F3(M2) in M.res;;
but even in this simple case the fix is ugly (and becomes uglier in
the real code). Maybe there is a way to avoid adding too many sharing
constraints?
BTW, the new manual has a section about common polymorphism
pitfalls. Modules also have a fair share of dark corners (along with
the objects). Perhaps there could be a section in the manual about
not so obvious aspects of modules (in the first approximation,
just collecting questions and answers like the present one).
next reply other threads:[~2018-01-23 14:48 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-23 14:54 Oleg [this message]
2018-01-23 16:05 ` Jeremy Yallop
2018-01-23 17:39 ` Chet Murthy
2018-01-23 20:35 ` Jeremy Yallop
2018-01-23 21:36 ` Chet Murthy
2018-01-23 22:06 ` Jeremy Yallop
2018-01-23 23:14 ` Hendrik Boom
2018-01-24 1:06 ` Chet Murthy
2018-01-24 1:35 ` Francois BERENGER
2018-02-07 2:00 ` [Caml-list] [ANN] first release of bst: a bisector tree implementation Francois BERENGER
2018-02-07 12:40 ` Ivan Gotovchits
2018-02-08 0:46 ` Francois BERENGER
2018-01-24 1:56 ` [Caml-list] Are record types generative? Yawar Amin
2018-01-25 10:49 ` Matej Košík
2018-01-25 13:39 ` Simon Cruanes
2018-01-25 16:24 ` Yawar Amin
2018-01-24 1:05 ` Chet Murthy
2018-01-24 8:43 ` Jacques Garrigue
2018-02-02 23:07 ` Toby Kelsey
2018-02-02 23:23 ` Evgeny Roubinchtein
2018-02-04 1:27 ` Jacques Garrigue
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180123145453.GA1916@Magus.localnet \
--to=oleg@okmij.org \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox