From: David Allsopp <dra-news@metastack.com>
To: OCaml List <caml-list@inria.fr>
Subject: RE: [Caml-list] Anonymous sum types in functors
Date: Mon, 24 Jun 2013 09:39:23 +0000 [thread overview]
Message-ID: <E51C5B015DBD1348A1D85763337FB6D9CC8678F2@Remus.metastack.local> (raw)
In-Reply-To: <FE6DC106-80C6-4E4B-B8AE-2F97DC90A950@math.nagoya-u.ac.jp>
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
next prev parent reply other threads:[~2013-06-24 9:39 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-23 7:16 David Allsopp
2013-06-23 15:14 ` Xavier Leroy
2013-06-23 23:15 ` Jacques Garrigue
2013-06-24 9:39 ` David Allsopp [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E51C5B015DBD1348A1D85763337FB6D9CC8678F2@Remus.metastack.local \
--to=dra-news@metastack.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox