caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* 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

* 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

* 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-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  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-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-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
  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  7:16 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

* [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

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 --
     [not found] <563607038852382852@orange.fr>
2013-06-23  9:48 ` [Caml-list] Anonymous sum types in functors David Allsopp
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).