From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id pA307ZNS001346 for ; Thu, 3 Nov 2011 01:07:35 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsQBAJPasU7RVdQ2kGdsb2JhbABEFoI3lz2HeQGHbAgiAQEBAQkJDQcUBCGBcgEBAQMBEgIsARsSCwEDAQsGBQsGAwECAQ0TAQ0hAhEBBQEKCggGExIJB4dgCJdpCotUgmCFWz2IcAIFCoM5hGxhBJQUhTGBLYNdgn49hAs X-IronPort-AV: E=Sophos;i="4.69,446,1315173600"; d="scan'208,217";a="116422029" Received: from mail-vw0-f54.google.com ([209.85.212.54]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 03 Nov 2011 01:07:29 +0100 Received: by vws11 with SMTP id 11so1120397vws.27 for ; Wed, 02 Nov 2011 17:07:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=cc:message-id:from:to:in-reply-to:content-type:mime-version:subject :date:references:x-mailer; bh=Z7hdYJypSvX6PylX4bP6QvNPfmmEwspNIsdvU77Cz9Y=; b=XDUY0ym1ykn9MLOi4wqcEEqOQ1J+Q7vxbHZzhUQrvKWrQGuaDdp6jP9KXwhUFcl6sv d/QPK3LWDzNV3hRUm1XLbsdDD/u5u6NHsnjrL3BzZFMxUYEor33BJpSZvOOjI4ggcJJy kupQ87afXJCp2OJatGToYAPbqDeMpTqeEVICs= Received: by 10.52.90.80 with SMTP id bu16mr6907414vdb.113.1320278847091; Wed, 02 Nov 2011 17:07:27 -0700 (PDT) Received: from [192.168.0.120] (modemcable190.109-177-173.mc.videotron.ca. [173.177.109.190]) by mx.google.com with ESMTPS id r5sm5432324vdj.11.2011.11.02.17.07.12 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 02 Nov 2011 17:07:24 -0700 (PDT) Cc: Anthony Tavener , caml-list@inria.fr Message-Id: <463546F9-F034-4968-BA62-443CAFD67F93@gmail.com> From: Vincent Aravantinos To: Gabriel Scherer In-Reply-To: Content-Type: multipart/alternative; boundary=Apple-Mail-1-521692719 Mime-Version: 1.0 (Apple Message framework v936) Date: Wed, 2 Nov 2011 20:06:32 -0400 References: <4EB1A5DB.8070405@gmail.com> X-Mailer: Apple Mail (2.936) Subject: Re: [Caml-list] Nested module exposing type from parent? --Apple-Mail-1-521692719 Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes Content-Transfer-Encoding: quoted-printable Maybe I am wrong but I have the feeling that this is totally unrelated=20= =20 to Anthony's question? Could you please explain in more details how it solves the problem? I actually tried your solution on Anthony's code but it does not solve=20= =20 his problem (if I understood it well of course). -- Vincent Aravantinos PostDoctoral fellow, Concordia University, Hardware Verification Group http://users.encs.concordia.ca/~vincent Le 2 nov. 11 =E0 19:01, Gabriel Scherer a =E9crit : > I see that you solved your problem in a way you find satisfying, but I > would like to point out that the reason why your original code didn't > work isn't exactly what you seem to think. > > When you define a submodule, the types defined before in the parent > modules are perfectly accessible and can be referred, just as you > would do when referring to types defined at the toplevel. You need not > qualify the type with the outer module name (Vec.t in your example), > as you are still *inside* this parent module. > > module Vec =3D struct > type t =3D int > module Type =3D struct > type u =3D t > end > end > > (1 : Vec.Type.u);; > > The problem in your case is that you wish to give the same name to the > type in Vec and in Vec.Type. This would lead to the following: > ... module Type =3D struct type t =3D t end ... > > But this is ill-defined : it is a recursive type defined as being > itself. The problem is that the OCaml syntax for type declarations > always consider them recursive (for values you have "let" and "let > rec", for types you have "type" which behaves like "type rec" with no > opt-out way possible). This is a flaw of the OCaml syntax which is > relatively well-known, see eg. http://ocaml.janestreet.com/?q=3Dnode/25 > > A workaround is to define your inner type "t" in two steps, using an > different intermediate name to break the cycle: > > module Vec =3D struct > type t =3D int > module Type =3D struct > type u =3D t > type t =3D u > end > end > > (1 : Vec.Type.t);; > > > On Wed, Nov 2, 2011 at 10:14 PM, Anthony Tavener > wrote: >> Oops, I didn't do a group-reply... so in case anyone is interested=20=20 >> in what I >> ended up with: >> >> ---------- Forwarded message ---------- >> From: Anthony Tavener >> Date: Wed, Nov 2, 2011 at 2:50 PM >> Subject: Re: [Caml-list] Nested module exposing type from parent? >> To: Vincent Aravantinos >> >> >> Actually, better than I initially thought... >> I keep this as I have them defined already, except as you said:=20=20 >> include >> instead of open. >> module Vec =3D struct >> module Type =3D struct >> type t =3D { x: int; y: int } >> end >> include Type >> let make x y =3D {x;y} >> let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.y} >> end >> Before, I had instead of the include: >> type t =3D Type.t >> open Type >> Which worked, but then the type used everywhere was Vec.Type.t >> Thanks again! Simple and effective, and I was looking in all the=20=20 >> wrong >> places. :) >> On Wed, Nov 2, 2011 at 2:36 PM, Anthony Tavener > > >> wrote: >>> >>> Thank-you Vincent! >>> Though this requires a home for the "source type" module, at least=20= =20 >>> the >>> types come out right in the end. Thanks! >>> And this led me to read specifically about include to understand=20=20 >>> what it >>> really does. :) >>> >>> On Wed, Nov 2, 2011 at 2:19 PM, Vincent Aravantinos >>> wrote: >>>> >>>> Using "include" instead of "open" would work, ie. turning your=20=20 >>>> example >>>> into: >>>> >>>> module Vec_main =3D struct >>>> type t =3D { x: int; y: int } >>>> let make x y =3D {x;y} >>>> let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.y} >>>> end >>>> >>>> module Vec =3D struct >>>> include Vec_main >>>> module Type =3D struct >>>> include Vec_main >>>> ... >>>> end >>>> end >>>> >>>> Then: >>>> # let n =3D Vec.make 2 5;; >>>> val n : Vec.t =3D {Vec.x =3D 2; Vec.y =3D 5} >>>> # open Vec.Type;; >>>> # let m =3D {x=3D1;y=3D2};; >>>> val m : Vec.Type.t =3D {x =3D 1; y =3D 2} >>>> # Vec.add m n;; >>>> - : Vec.t =3D {Vec.x =3D 3; Vec.y =3D 7} >>>> >>>> Cheers >>>> >>>> -- >>>> Vincent Aravantinos - Postdoctoral Fellow, Concordia University,=20=20 >>>> Hardware >>>> Verification Group >>>> >>>> On 11/02/2011 03:41 PM, Anthony Tavener wrote: >>>> >>>> I've been struggling with this occasionally... >>>> I'm using nested modules to "open" access to select features of a=20= =20 >>>> module. >>>> My problem is I can't find a way to *expose* types in the parent=20=20 >>>> module >>>> through such nested modules. >>>> A simplified example of what I'm looking at: >>>> module Vec =3D struct >>>> type t =3D { x: int; y: int } >>>> let make x y =3D {x;y} >>>> let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.y} >>>> module Type =3D >>>> (* something which has type t =3D Vec.t, >>>> * with exposed structure when "open"ed. >>>> * Also note that Vec is not really an >>>> * explicit module like this; instead it >>>> * is implemented in vec.ml *) >>>> end >>>> Example usage... >>>> let n =3D Vec.make 2 5 >>>> open Vec.Type >>>> let m =3D {x=3D1;y=3D2} >>>> Vec.add m n >>>> >>>> To date, I've defined the type in the Type submodule, which is=20=20 >>>> then used >>>> by the parent module. The unsatisfactory quality of this is that=20=20 >>>> Vec.Type.t >>>> is the "true" type. Ideally the concrete type would live at=20=20 >>>> Vec.t, with >>>> "open Vec.Type" bringing the fields of the type into scope. >>>> As background, here are examples of opening different features of=20= =20 >>>> the Vec >>>> module: >>>> let c =3D Vec.add a b >>>> open Vec.Prefixed >>>> let c =3D vadd a b >>>> open Vec.Ops >>>> let c =3D a +| b >>>> open Vec.Type >>>> let c =3D Vec.add a {x;y;z=3D0.} >>>> Apologies if this is really beginner-list material. It's minor,=20=20 >>>> but has >>>> been bugging me. >>>> Thank-you for looking, >>>> Tony >>>> >>> >> >> >> > > > --=20 > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > --Apple-Mail-1-521692719 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Maybe I am wrong but I have the feeling= that this is totally unrelated to Anthony's question?
Could you please= explain in more details how it solves the problem?
I actually tr= ied your solution on Anthony's code but it does not solve his problem (if I= understood it well of course).

<= div>--
PostDoctoral fel= low, Concordia University, Hardware Verification Grouphttp= ://users.encs.concordia.ca/~vincent


Le 2 = nov. 11 =E0 19:01, Gabriel Scherer a =E9crit :

I see that you solved your = problem in a way you find satisfying, but I
would like to point out that= the reason why your original code didn't
work isn't exactly what you se= em to think.

When you define a submodule, the types defined before i= n the parent
modules are perfectly accessible and can be referred, just = as you
would do when referring to types defined at the toplevel. You nee= d not
qualify the type with the outer module name (Vec.t in your example= ),
as you are still *inside* this parent module.

 module Ve= c =3D struct
   type t =3D int
   mod= ule Type =3D struct
     type u =3D t
&nbs= p;  end
 end

 (1 : Vec.Type.u);;

The= problem in your case is that you wish to give the same name to the
type= in Vec and in Vec.Type. This would lead to the following:
 ... mo= dule Type =3D struct type t =3D t end ...

But this is ill-defined : = it is a recursive type defined as being
itself. The problem is that the = OCaml syntax for type declarations
always consider them recursive (for v= alues you have "let" and "let
rec", for types you have "type" which beha= ves like "type rec" with no
opt-out way possible). This is a flaw of the= OCaml syntax which is
relatively well-known, see eg. http://ocaml.janestreet.com/?q=3Dnode/25=

A workaround is to define your inner type "t" in two steps, usi= ng an
different intermediate name to break the cycle:

 modu= le Vec =3D struct
   type t =3D int
  &nbs= p;module Type =3D struct
     type u =3D t
=      type t =3D u
   end
&= nbsp;end

 (1 : Vec.Type.t);;


On Wed, Nov 2, 2011 at= 10:14 PM, Anthony Tavener
<anthony.tavener@gmail.com> wrote:
O= ops, I didn't do a group-reply... so in case anyone is interested in what I=
ended up with:
<= blockquote type=3D"cite">
-------= --- Forwarded message ----------
= From: Anthony Tavener <anth= ony.tavener@gmail.com>
Dat= e: Wed, Nov 2, 2011 at 2:50 PM
Su= bject: Re: [Caml-list] Nested module exposing type from parent?
To: Vincent Aravantinos <vincent.aravantinos@gmail.com>
<= /blockquote>


Actually, better than I in= itially thought...
I keep this as= I have them defined already, except as you said: include
<= blockquote type=3D"cite">instead of open.
  module Vec =3D struct
    module Type =3D struct
      type t =3D { x: int; y: int }
    end
    include Type
    let make x y =3D {x;y}
    let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.y}
  end
Before, I had instead of the include:
  type t =3D Type.t
  open Type
Which = worked, but then the type used everywhere was Vec.Type.t
Thanks again! Simple and effective, and I was looki= ng in all the wrong
places. :)
On Wed, Nov 2, 2011 at 2:36 PM, Ant= hony Tavener <anthony.taven= er@gmail.com>
wrote:

Thank= -you Vincent!
Though this requires a home for the "source type" modul= e, at least the
types come out right in the end. Thanks!
And th= is led me to read specifically about include to understand what it
re= ally does. :)

On Wed, Nov 2, 2011 at 2:19 PM, Vincent Aravanti= nos
<vincent.arav= antinos@gmail.com> wrote:

Using "include" instead of "open" would= work, ie. turning your example
<= blockquote type=3D"cite">
into:

module Vec_main =3D struct
  type t =3D { x: int; y: int }
<= /blockquote>
  let make x y =3D {x;y}
<= /blockquote>
  let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.= y}
end

module = Vec =3D struct
  includ= e Vec_main
  module Type = =3D struct
    = include Vec_main
  &= nbsp; ...
  end
end

Then:
# let n =3D Vec.make 2 5;;
=
val n : Vec.t =3D {Vec.x =3D 2; Vec.y =3D 5}
# open Vec.Type;;
# let m =3D {x=3D1;y=3D2};;
val m : Vec.Type.t =3D {x =3D 1; y =3D 2}
=
# Vec.add m n;;
<= /blockquote>
- : Vec.t =3D {Vec.x =3D 3; Vec.y =3D 7}

Cheers

--
Vincent Aravantinos - Postdoctoral Fellow, Concordia University, Hard= ware
Verification Group

On 11/02/2011 03:41 PM, Anthony Tavener wrote:

I'= ve been struggling with this occasionally...
<= /blockquote>
I'm using nested modules to "open" access to select features= of a module.
My problem is I = can't find a way to *expose* types in the parent module
=
through such nested modules.
<= blockquote type=3D"cite">A simplified example of what I'm looking at:
  module Vec =3D struct
    type t =3D { x: int; y= : int }
    let make= x y =3D {x;y}
   = let add a b =3D {x=3Da.x+b.x; y=3Da.y+b.y}
    module Type =3D
      (* something which has type t =3D Vec.t,=
       * = with exposed structure when "open"ed.
       * Also note that Vec is not really an<= br>
       * e= xplicit module like this; instead it
       * is implemented in vec.ml *)
  end
Example usage...
  let n =3D Vec.make 2 5
  open Vec.Type
 = ; let m =3D {x=3D1;y=3D2}
&nbs= p; Vec.add m n

To date, I've defined the type in the Type= submodule, which is then used
by the parent module. The unsatisfactory quality of this is that Vec.Type.= t
is the "true" type. Ideally = the concrete type would live at Vec.t, with
"open Vec.Type" bringing the fields of the type into scope.
As background, here are example= s of opening different features of the Vec
module:
  le= t c =3D Vec.add a b
  ope= n Vec.Prefixed
  let c = =3D vadd a b
  open Vec.O= ps
  let c =3D a +| b
=
  open Vec.Type
  let c =3D Vec.add a {x;y;z=3D0.}
Apologies if this is really begi= nner-list material. It's minor, but has
been bugging me.
Tha= nk-you for looking,
 Tony=





=

--
Caml-list mailing list.  Subscription management and ar= chives:
https:= //sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://grou= ps.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin= /caml-bugs


= --Apple-Mail-1-521692719--