* [Caml-list] Anonymous sum types in functors @ 2013-06-23 7:16 David Allsopp 2013-06-23 15:14 ` Xavier Leroy 2013-06-23 23:15 ` Jacques Garrigue 0 siblings, 2 replies; 9+ messages in thread From: David Allsopp @ 2013-06-23 7:16 UTC (permalink / raw) To: OCaml List [-- Attachment #1: Type: text/plain, Size: 1264 bytes --] I couldn't think of a better way to describe what I'm trying to do, so forgive the possibly strange subject! In: module IntSet = Set.Make(struct type t = int let compare = compare end) the resulting signature is: sig type elt = int type t ... but in: module FlagSet = Set.Make(struct type t = A | B let compare = compare end) the resulting signature is: sig type elt type t ... i.e. the constructors are hidden (I can see why, but presumably it is a special case in the type checker?) and the module is essentially useless. I don't want to define the type external to the module - the idea is that I'd be able to write Flag1Set.add Flag1Set.CommonFlag Flag1Set.empty and Flag2Set.add Flag2Set.CommonFlag Flag2Set.empty, etc. I can work around this by writing: module FlagSet = struct type flag = A | B include Set.Make(struct type t = flag let compare = compare end) end where the resulting signature is: sig type flag = A | B type elt = flag type t ... but I'm wondering: a) Is there a way to do it where you can end up with type elt = A | B (I think the answer is no?) b) Is there a syntactically lighter way to write the module definition? David [-- Attachment #2: Type: text/html, Size: 5227 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] Anonymous sum types in functors 2013-06-23 7:16 [Caml-list] Anonymous sum types in functors David Allsopp @ 2013-06-23 15:14 ` Xavier Leroy 2013-06-23 23:15 ` Jacques Garrigue 1 sibling, 0 replies; 9+ messages in thread From: Xavier Leroy @ 2013-06-23 15:14 UTC (permalink / raw) To: caml-list On 23/06/13 09:16, David Allsopp wrote: > a) Is there a way to do it where you can end up with type elt = A | B (I > think the answer is no?) No, because that wouldn't quite respect the generativity of sum type definitions, but you can get close, see below. > b) Is there a syntactically lighter way to write the module definition? I would recommend naming your anonymous "struct": module Flag = struct type t = A | B let compare = compare (* Other useful operations over flags, e.g. *) let to_string = function A -> "A" | B -> "B" end module FlagSet = Set.Make(Flag) Then you get FlagSet: sig type elt = Flag.t type t ... end The good thing about this solution is that it gives you a natural place to put additional operations over flags, like "to_string" above, shall you ever need them. > the idea is that I'd > be able to write Flag1Set.add Flag1Set.CommonFlag Flag1Set.empty and > Flag2Set.add Flag2Set.CommonFlag Flag2Set.empty, etc. Why not "Flag1Set.add Flag1.CommonFlag Flag1Set.empty"? Flags morally come from Flag1, not from Flag1Set. As an aside, some ML-like module systems require functor arguments to be module names or paths, e.g. Coq's. OCaml accepts anonymous structs as arguments, and does the best it can with them, but if the struct contains generative type definitions, some information is necessarily lost. Hope this helps, - Xavier Leroy ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] Anonymous sum types in functors 2013-06-23 7:16 [Caml-list] Anonymous sum types in functors David Allsopp 2013-06-23 15:14 ` Xavier Leroy @ 2013-06-23 23:15 ` Jacques Garrigue 2013-06-24 9:39 ` David Allsopp 1 sibling, 1 reply; 9+ messages in thread From: Jacques Garrigue @ 2013-06-23 23:15 UTC (permalink / raw) To: David Allsopp; +Cc: OCaml List On 2013/06/23, at 16:16, David Allsopp <dra-news@metastack.com> wrote: > module FlagSet = Set.Make(struct type t = A | B let compare = compare end) [doesn't work] > but I'm wondering: > > a) Is there a way to do it where you can end up with type elt = A | B (I think the answer is no?) Xavier described the official solution. However, since 3.12 you can also do some trickery. This is going to be heavier, so this is probably a bad idea, but if you really need it, here it is: module FlagSet = struct type elt = A | B include (Set.Make (struct type t = elt let compare = compare end) : Set.S with type elt := elt) end Jacques Garrigue ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [Caml-list] Anonymous sum types in functors 2013-06-23 23:15 ` Jacques Garrigue @ 2013-06-24 9:39 ` David Allsopp 2013-06-24 14:37 ` Kristopher Micinski 0 siblings, 1 reply; 9+ messages in thread From: David Allsopp @ 2013-06-24 9:39 UTC (permalink / raw) To: OCaml List Xavier Leroy wrote: > On 23/06/13 09:16, David Allsopp wrote: > > b) Is there a syntactically lighter way to write the module definition? > > I would recommend naming your anonymous "struct": > > module Flag = struct > type t = A | B > let compare = compare > (* Other useful operations over flags, e.g. *) > let to_string = function A -> "A" | B -> "B" > end The "reason" for wanting to avoid that in this instance is the specific application - the sets are actually bit masks and there are about 50 of them (using a code generator, unsurprisingly). Given that the ocamldoc output is already going to be interesting, I was trying to avoid having 100 modules if possible :o) <snip> > Why not "Flag1Set.add Flag1.CommonFlag Flag1Set.empty"? Flags morally > come from Flag1, not from Flag1Set. Totally agree - this is just a slightly unusual case, I think. In my actual implementation, the module is really called Flag1 and it happens to include the set operations, so the operations that morally belong to Flag1Set are in fact in Flag1 - but it doesn't look that weird in context. > As an aside, some ML-like module systems require functor arguments to be > module names or paths, e.g. Coq's. OCaml accepts anonymous structs as > arguments, and does the best it can with them, but if the struct contains > generative type definitions, some information is necessarily lost. > > Hope this helps, It did, thank you! As did: Jacques Garrigue wrote: > > module FlagSet = Set.Make(struct type t = A | B let compare = compare > > end) > [doesn't work] > > but I'm wondering: > > > > a) Is there a way to do it where you can end up with type elt = A | B > > (I think the answer is no?) > > Xavier described the official solution. > However, since 3.12 you can also do some trickery. > This is going to be heavier, so this is probably a bad idea, but if you > really need it, here it is: > > module FlagSet = struct > type elt = A | B > include (Set.Make (struct type t = elt let compare = compare end) : > Set.S with type elt := elt) end Fab, thanks - I had attempted something along these lines but couldn't quite get the syntax right. As I say, a slightly unusual use case as one wouldn't normally care about creating the extra module to house the type (and anything related to it). Whether there was a lighter syntax was just a curiosity, rather than a need (having written full signatures for Sets and Maps years ago before discovering include Set.S with ...!). David ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] Anonymous sum types in functors 2013-06-24 9:39 ` David Allsopp @ 2013-06-24 14:37 ` Kristopher Micinski 2013-06-24 14:41 ` Raphaël Proust 2013-06-25 8:39 ` David Allsopp 0 siblings, 2 replies; 9+ messages in thread From: Kristopher Micinski @ 2013-06-24 14:37 UTC (permalink / raw) To: David Allsopp; +Cc: OCaml List On Mon, Jun 24, 2013 at 5:39 AM, David Allsopp <dra-news@metastack.com> wrote: > Xavier Leroy wrote: >> On 23/06/13 09:16, David Allsopp wrote: >> > b) Is there a syntactically lighter way to write the module definition? >> >> I would recommend naming your anonymous "struct": >> >> module Flag = struct >> type t = A | B >> let compare = compare >> (* Other useful operations over flags, e.g. *) >> let to_string = function A -> "A" | B -> "B" >> end > > The "reason" for wanting to avoid that in this instance is the specific application - the sets are actually bit masks and there are about 50 of them (using a code generator, unsurprisingly). Given that the ocamldoc output is already going to be interesting, I was trying to avoid having 100 modules if possible :o) This honestly sounds like something that you should be able to avoid in OCamlDoc. It seems sensible you should be able to mark things as "don't generate documentation for these", but I havent' seen such. Kris ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] Anonymous sum types in functors 2013-06-24 14:37 ` Kristopher Micinski @ 2013-06-24 14:41 ` Raphaël Proust 2013-06-24 19:13 ` Kristopher Micinski 2013-06-25 8:39 ` David Allsopp 1 sibling, 1 reply; 9+ messages in thread From: Raphaël Proust @ 2013-06-24 14:41 UTC (permalink / raw) To: Kristopher Micinski; +Cc: David Allsopp, OCaml List On Mon, Jun 24, 2013 at 3:37 PM, Kristopher Micinski <krismicinski@gmail.com> wrote: >> >> The "reason" for wanting to avoid that in this instance is the specific application - the sets are actually bit masks and there are about 50 of them (using a code generator, unsurprisingly). Given that the ocamldoc output is already going to be interesting, I was trying to avoid having 100 modules if possible :o) > > This honestly sounds like something that you should be able to avoid > in OCamlDoc. It seems sensible you should be able to mark things as > "don't generate documentation for these", but I havent' seen such. From: http://caml.inria.fr/pub/docs/manual-ocaml/manual029.html#toc120 The special comment (**/**) tells OCamldoc to discard elements placed after this comment, up to the end of the current class, class type, module or module type, or up to the next stop comment. Cheers, -- ______________ Raphaël Proust ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Caml-list] Anonymous sum types in functors 2013-06-24 14:41 ` Raphaël Proust @ 2013-06-24 19:13 ` Kristopher Micinski 0 siblings, 0 replies; 9+ messages in thread From: Kristopher Micinski @ 2013-06-24 19:13 UTC (permalink / raw) To: Raphaël Proust; +Cc: David Allsopp, OCaml List Great, I googled for this, but didn't turn up anything: it seems sensible this would exist. Kris On Mon, Jun 24, 2013 at 10:41 AM, Raphaël Proust <raphlalou@gmail.com> wrote: > On Mon, Jun 24, 2013 at 3:37 PM, Kristopher Micinski > <krismicinski@gmail.com> wrote: >>> >>> The "reason" for wanting to avoid that in this instance is the specific application - the sets are actually bit masks and there are about 50 of them (using a code generator, unsurprisingly). Given that the ocamldoc output is already going to be interesting, I was trying to avoid having 100 modules if possible :o) >> >> This honestly sounds like something that you should be able to avoid >> in OCamlDoc. It seems sensible you should be able to mark things as >> "don't generate documentation for these", but I havent' seen such. > > From: http://caml.inria.fr/pub/docs/manual-ocaml/manual029.html#toc120 > > The special comment (**/**) tells OCamldoc to discard elements placed > after this comment, up to the end of the current class, class type, > module or module type, or up to the next stop comment. > > > Cheers, > -- > ______________ > Raphaël Proust ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [Caml-list] Anonymous sum types in functors 2013-06-24 14:37 ` Kristopher Micinski 2013-06-24 14:41 ` Raphaël Proust @ 2013-06-25 8:39 ` David Allsopp 1 sibling, 0 replies; 9+ messages in thread From: David Allsopp @ 2013-06-25 8:39 UTC (permalink / raw) To: OCaml List (caml-list@inria.fr) Kristopher Micinski wrote: > On Mon, Jun 24, 2013 at 5:39 AM, David Allsopp > <dra-news@metastack.com> > wrote: > > Xavier Leroy wrote: > >> On 23/06/13 09:16, David Allsopp wrote: > >> > b) Is there a syntactically lighter way to write the module > definition? > >> > >> I would recommend naming your anonymous "struct": > >> > >> module Flag = struct > >> type t = A | B > >> let compare = compare > >> (* Other useful operations over flags, e.g. *) > >> let to_string = function A -> "A" | B -> "B" > >> end > > > > The "reason" for wanting to avoid that in this instance is the > > specific application - the sets are actually bit masks and there are > > about 50 of them (using a code generator, unsurprisingly). Given > > that the ocamldoc output is already going to be interesting, I was > > trying to avoid having 100 modules if possible :o) > > This honestly sounds like something that you should be able to avoid > in OCamlDoc. It seems sensible you should be able to mark things as > "don't generate documentation for these", but I havent' seen such. (**/**) is mentioned in the manual for ocamldoc (and used in the standard library, typically to "hide" the documentation for unsafe functions) - see 15.2.2 of the reference manual. All these types do need documenting :o) But splitting the documentation for each concept across two modules will necessarily make the documentation physically longer! David ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <563607038852382852@orange.fr>]
* Re: [Caml-list] Anonymous sum types in functors [not found] <563607038852382852@orange.fr> @ 2013-06-23 9:48 ` David Allsopp 0 siblings, 0 replies; 9+ messages in thread From: David Allsopp @ 2013-06-23 9:48 UTC (permalink / raw) To: OCaml List [-- Attachment #1: Type: text/plain, Size: 2042 bytes --] On 23 Jun 2013, at 10:13, "Damien Guichard" <alphablock@orange.fr<mailto:alphablock@orange.fr>> wrote: > a) Is there a way to do it where you can end up with type elt = A | B (I think the answer is no?) > b) Is there a syntactically lighter way to write the module definition? My own quick & dirty hack : module FlagSet = Set.Make(struct type t = [`A | `B] let compare = compare end) Sadly not - the values are in use with C bindings and polymorphic variants would rather defeat the point of what I'm doing! What would be nice would be an equivalent 'immediate' syntax for variant types - but its only use would be this context, I expect! David - damien I couldn't think of a better way to describe what I'm trying to do, so forgive the possibly strange subject! In: module IntSet = Set.Make(struct type t = int let compare = compare end) the resulting signature is: sig type elt = int type t ... but in: module FlagSet = Set.Make(struct type t = A | B let compare = compare end) the resulting signature is: sig type elt type t ... i.e. the constructors are hidden (I can see why, but presumably it is a special case in the type checker?) and the module is essentially useless. I don't want to define the type external to the module - the idea is that I'd be able to write Flag1Set.add Flag1Set.CommonFlag Flag1Set.empty and Flag2Set.add Flag2Set.CommonFlag Flag2Set.empty, etc. I can work around this by writing: module FlagSet = struct type flag = A | B include Set.Make(struct type t = flag let compare = compare end) end where the resulting signature is: sig type flag = A | B type elt = flag type t ... but I'm wondering: a) Is there a way to do it where you can end up with type elt = A | B (I think the answer is no?) b) Is there a syntactically lighter way to write the module definition? David [-- Attachment #2: Type: text/html, Size: 6414 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-06-25 8:39 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-06-23 7:16 [Caml-list] Anonymous sum types in functors David Allsopp 2013-06-23 15:14 ` Xavier Leroy 2013-06-23 23:15 ` Jacques Garrigue 2013-06-24 9:39 ` David Allsopp 2013-06-24 14:37 ` Kristopher Micinski 2013-06-24 14:41 ` Raphaël Proust 2013-06-24 19:13 ` Kristopher Micinski 2013-06-25 8:39 ` David Allsopp [not found] <563607038852382852@orange.fr> 2013-06-23 9:48 ` David Allsopp
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox