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 tried your solution on Anthony's code but it does not solve 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 à 19:01, Gabriel Scherer a écrit : > 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 = struct > type t = int > module Type = struct > type u = 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 = struct type t = 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=node/25 > > A workaround is to define your inner type "t" in two steps, using an > different intermediate name to break the cycle: > > module Vec = struct > type t = int > module Type = struct > type u = t > type t = 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 >> 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: >> include >> instead of open. >> module Vec = struct >> module Type = struct >> type t = { x: int; y: int } >> end >> include Type >> let make x y = {x;y} >> let add a b = {x=a.x+b.x; y=a.y+b.y} >> end >> Before, I had instead of the include: >> type t = 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 >> 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 >>> the >>> types come out right in the end. Thanks! >>> And this led me to read specifically about include to understand >>> 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 >>>> example >>>> into: >>>> >>>> module Vec_main = struct >>>> type t = { x: int; y: int } >>>> let make x y = {x;y} >>>> let add a b = {x=a.x+b.x; y=a.y+b.y} >>>> end >>>> >>>> module Vec = struct >>>> include Vec_main >>>> module Type = struct >>>> include Vec_main >>>> ... >>>> end >>>> end >>>> >>>> Then: >>>> # let n = Vec.make 2 5;; >>>> val n : Vec.t = {Vec.x = 2; Vec.y = 5} >>>> # open Vec.Type;; >>>> # let m = {x=1;y=2};; >>>> val m : Vec.Type.t = {x = 1; y = 2} >>>> # Vec.add m n;; >>>> - : Vec.t = {Vec.x = 3; Vec.y = 7} >>>> >>>> Cheers >>>> >>>> -- >>>> Vincent Aravantinos - Postdoctoral Fellow, Concordia University, >>>> 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 >>>> module. >>>> My problem is I can't find a way to *expose* types in the parent >>>> module >>>> through such nested modules. >>>> A simplified example of what I'm looking at: >>>> module Vec = struct >>>> type t = { x: int; y: int } >>>> let make x y = {x;y} >>>> let add a b = {x=a.x+b.x; y=a.y+b.y} >>>> module Type = >>>> (* something which has type t = 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 = Vec.make 2 5 >>>> open Vec.Type >>>> let m = {x=1;y=2} >>>> 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 examples of opening different features of >>>> the Vec >>>> module: >>>> let c = Vec.add a b >>>> open Vec.Prefixed >>>> let c = vadd a b >>>> open Vec.Ops >>>> let c = a +| b >>>> open Vec.Type >>>> let c = Vec.add a {x;y;z=0.} >>>> Apologies if this is really beginner-list material. It's minor, >>>> but has >>>> been bugging me. >>>> Thank-you for looking, >>>> Tony >>>> >>> >> >> >> > > > -- > 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 >