Re: [Caml-list] Nested module exposing type from parent?
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 opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://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
Re: [Caml-list] Nested module exposing type from parent?
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 anthony.tave...@gmail.com 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 anthony.tave...@gmail.com Date: Wed, Nov 2, 2011 at 2:50 PM Subject: Re: [Caml-list] Nested module exposing type from parent? To: Vincent Aravantinos vincent.aravanti...@gmail.com 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 anthony.tave...@gmail.com 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 vincent.aravanti...@gmail.com 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 opened. * 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
Re: [Caml-list] Nested module exposing type from parent?
On 11/02/2011 12: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 opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end Example usage... let n = Vec.make 2 5 open Vec.Type let m = {x=1;y=2} Vec.add m n I hope I understand the problem correctly. In order for that code to work, you can do this: 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 = struct type t' = t = { x: int; y: int } type t = t' = { x: int; y: int } (* something which has type t = Vec.t, * with exposed structure when opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end end Or more simply: module Vec = struct module Type = struct type t = { x: int; y: int } (* something which has type t = Vec.t, * with exposed structure when opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end type t = 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 Now you can open either Vec or Vec.Type and have direct access to the record fields. Martin -- 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
Re: [Caml-list] Nested module exposing type from parent?
Aha! That's more like what I was going for, Martin. I didn't realize you could equate types in a chain like that, permitting the definition of structure but also equality to another existing type. That's good stuff. This list, and OCaml, often amaze me... solutions keep getting better. :) On Wed, Nov 2, 2011 at 6:41 PM, Martin Jambon martin.jam...@ens-lyon.orgwrote: On 11/02/2011 12: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 opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end Example usage... let n = Vec.make 2 5 open Vec.Type let m = {x=1;y=2} Vec.add m n I hope I understand the problem correctly. In order for that code to work, you can do this: 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 = struct type t' = t = { x: int; y: int } type t = t' = { x: int; y: int } (* something which has type t = Vec.t, * with exposed structure when opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end end Or more simply: module Vec = struct module Type = struct type t = { x: int; y: int } (* something which has type t = Vec.t, * with exposed structure when opened. * Also note that Vec is not really an * explicit module like this; instead it * is implemented in vec.ml http://vec.ml *) end type t = 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 Now you can open either Vec or Vec.Type and have direct access to the record fields. Martin -- 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 -- 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