From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.8 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE, DNS_FROM_RFC_POST,DNS_FROM_RFC_WHOIS autolearn=disabled version=3.1.3 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 2966FBBAF for ; Tue, 5 Aug 2008 17:09:00 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmEBAHQJmEjOvjGsmmdsb2JhbACRNwEBAQEBBgcIBxGcQA X-IronPort-AV: E=Sophos;i="4.31,310,1215381600"; d="scan'208";a="15741069" Received: from web54602.mail.re2.yahoo.com ([206.190.49.172]) by mail3-smtp-sop.national.inria.fr with SMTP; 05 Aug 2008 17:09:00 +0200 Received: (qmail 39999 invoked by uid 60001); 5 Aug 2008 15:08:59 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Received:X-Mailer:Date:From:Subject:To:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-ID; b=2W/eNcuUMi96QzPBEiNrrvFQsKBlvqs9L22GSj5RcaDsE71+M57DTh4cYvELRwuCrVmRSY5bBPYMHuWWED4fN0E3EeocPl+IbvMZLizXwymi16xmrIhhOEOlnUIUP9FTpdG85q+hvWZDOtWYU4vcX5ilKUotHoEaReTZ+8Plc7U=; Received: from [212.13.63.219] by web54602.mail.re2.yahoo.com via HTTP; Tue, 05 Aug 2008 08:08:58 PDT X-Mailer: YahooMailWebService/0.7.218 Date: Tue, 5 Aug 2008 08:08:58 -0700 (PDT) From: Dario Teixeira Subject: Private and type constraints To: caml-list@yquem.inria.fr MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Message-ID: <982865.39461.qm@web54602.mail.re2.yahoo.com> X-Spam: no; 0.00; constructors:01 abstracting:01 variants:01 foobar:01 sig:01 foo:01 foobar:01 foo:01 val:01 val:01 struct:01 bool:01 toplevel:01 ocamlc:01 ocamlopt:01 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 =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ foo_t | bar_t ] type t =3D private [< foobar_t ] val make_a: unit -> t val make_b: unit -> t end =3D struct type foo_t =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ foo_t | bar_t ] type t =3D foobar_t let make_a () =3D `A let make_b () =3D `B end # open Foobar;; # let ola =3D make_a ();; val ola : Foobar.t =3D `A # match ola with `A -> true | `B -> false;; - : bool =3D true # let ola2 : Foobar.t =3D `A;; Characters 22-24: let ola2 : Foobar.t =3D `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 con= straint. There are however two problems: first, the code below is accepted by the to= plevel, 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 usin= g the constructor functions, pattern-matching is unfortunately also disallowed. module Foobar2: sig type foo_t =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ foo_t | bar_t ] type 'a t =3D private 'a constraint 'a =3D [< foobar_t ] val make_a: unit -> foo_t t val make_b: unit -> bar_t t end =3D struct type foo_t =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ foo_t | bar_t ] type 'a t =3D 'a constraint 'a =3D [< foobar_t ] let make_a () =3D `A let make_b () =3D `B end # open Foobar2;; # let ola =3D make_a ();; val ola : Foobar2.foo_t Foobar2.t =3D `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 =3D `A;; Characters 37-39: let ola2 : Foobar2.foo_t Foobar2.t =3D `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 =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ `A | `B ] type 'a t =3D 'a Foobar2.t constraint 'a =3D [< 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 =3D [ `A ] type bar_t =3D [ `B ] type foobar_t =3D [ `A | `B ] type 'a t =3D private 'a constraint 'a =3D [< 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 =3D 'a Foobar2.t constraint 'a =3D [< foobar_t ] is not included in type 'a t =3D private 'a constraint 'a =3D [< 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 =0A=0A=0A __________________________________________________________= =0ANot happy with your email address?.=0AGet the one you really want - mill= ions of new email addresses available now at Yahoo! http://uk.docs.yahoo.co= m/ymail/new.html