From: Dario Teixeira <darioteixeira@yahoo.com>
To: caml-list@yquem.inria.fr
Subject: Private and type constraints
Date: Tue, 5 Aug 2008 08:08:58 -0700 (PDT) [thread overview]
Message-ID: <982865.39461.qm@web54602.mail.re2.yahoo.com> (raw)
Hi,
With 'private', you can make sure that users of a module can only use
constructors to create values, while at the same type maintaining the
ability to pattern-match (which abstracting the type makes impossible).
With 3.10, this can also be done with polymorphic variants:
module Foobar:
sig
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ foo_t | bar_t ]
type t = private [< foobar_t ]
val make_a: unit -> t
val make_b: unit -> t
end =
struct
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ foo_t | bar_t ]
type t = foobar_t
let make_a () = `A
let make_b () = `B
end
# open Foobar;;
# let ola = make_a ();;
val ola : Foobar.t = `A
# match ola with `A -> true | `B -> false;;
- : bool = true
# let ola2 : Foobar.t = `A;;
Characters 22-24:
let ola2 : Foobar.t = `A;;
^^
Error: This expression has type [> `A ] but is here used with type Foobar.t
Types for tag `A are incompatible
Now, I want to do the same for a type 't' that is declared using a type constraint.
There are however two problems: first, the code below is accepted by the toplevel,
but not by the ocamlc/ocamlopt compilers (I'm running version 3.11+dev15); second,
while as expected it prevents the creation of Foobar2.t values without using the
constructor functions, pattern-matching is unfortunately also disallowed.
module Foobar2:
sig
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ foo_t | bar_t ]
type 'a t = private 'a constraint 'a = [< foobar_t ]
val make_a: unit -> foo_t t
val make_b: unit -> bar_t t
end =
struct
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ foo_t | bar_t ]
type 'a t = 'a constraint 'a = [< foobar_t ]
let make_a () = `A
let make_b () = `B
end
# open Foobar2;;
# let ola = make_a ();;
val ola : Foobar2.foo_t Foobar2.t = `A
# match ola with `A -> true;;
Characters 15-17:
match ola with `A -> true;;
^^
Error: This pattern matches values of type [< `A ]
but is here used to match values of type Foobar2.foo_t Foobar2.t
# let ola2 : Foobar2.foo_t Foobar2.t = `A;;
Characters 37-39:
let ola2 : Foobar2.foo_t Foobar2.t = `A;;
^^
Error: This expression has type [> `A ] but is here used with type
Foobar2.foo_t Foobar2.t
This is the error produced by the compiler:
Error: The implementation constraint.ml
does not match the interface (inferred signature):
Modules do not match:
sig
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ `A | `B ]
type 'a t = 'a Foobar2.t constraint 'a = [< foobar_t ]
val make_a : unit -> foo_t t
val make_b : unit -> bar_t t
end
is not included in
sig
type foo_t = [ `A ]
type bar_t = [ `B ]
type foobar_t = [ `A | `B ]
type 'a t = private 'a constraint 'a = [< foobar_t ]
val make_a : unit -> foo_t t
val make_b : unit -> bar_t t
end
Type declarations do not match:
type 'a t = 'a Foobar2.t constraint 'a = [< foobar_t ]
is not included in
type 'a t = private 'a constraint 'a = [< foobar_t ]
Any idea on what is going on? Also, is it at all possible to achieve
the 'private' semantics I am looking for with types declared using
a constraint? I know I can do it by boxing the type inside a dummy
union or a record, but I would like to avoid that hassle if possible.
Thanks for your time + best regards,
Dario Teixeira
__________________________________________________________
Not happy with your email address?.
Get the one you really want - millions of new email addresses available now at Yahoo! http://uk.docs.yahoo.com/ymail/new.html
next reply other threads:[~2008-08-05 15:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-05 15:08 Dario Teixeira [this message]
2008-08-09 16:08 ` [Caml-list] " Dario Teixeira
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=982865.39461.qm@web54602.mail.re2.yahoo.com \
--to=darioteixeira@yahoo.com \
--cc=caml-list@yquem.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