* 'a Set?
@ 2005-01-25 23:54 Mike Hamburg
2005-01-26 8:25 ` [Caml-list] " Jean-Christophe Filliatre
2005-01-26 9:13 ` Jon Harrop
0 siblings, 2 replies; 13+ messages in thread
From: Mike Hamburg @ 2005-01-25 23:54 UTC (permalink / raw)
To: caml-list
Is there any clean way to make a type 'a set, corresponding to Set.Make
of a module with type t='a and compare=Pervasives.compare? I'm trying
to make a module which uses sets of arbitrary types of objects, and I
don't want to have to make it a functor.
So in other words, I'd like to make a module AlphaSet with type
type 'a t,
val is_empty: 'a t -> bool
val mem: 'a -> 'a t -> bool,
etc.
instead of Set which is a functor producing
types t, elt
val is_empty: t -> bool
val mem: elt -> t -> bool,
etc.
Is there a clean way to do this without removing the code from set.ml
and modifying it?
Mike Hamburg
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-25 23:54 'a Set? Mike Hamburg
@ 2005-01-26 8:25 ` Jean-Christophe Filliatre
2005-01-26 10:13 ` Frédéric Gava
2005-01-26 9:13 ` Jon Harrop
1 sibling, 1 reply; 13+ messages in thread
From: Jean-Christophe Filliatre @ 2005-01-26 8:25 UTC (permalink / raw)
To: Mike Hamburg; +Cc: caml-list
Mike Hamburg writes:
> Is there any clean way to make a type 'a set, corresponding to Set.Make
> of a module with type t='a and compare=Pervasives.compare? I'm trying
> to make a module which uses sets of arbitrary types of objects, and I
> don't want to have to make it a functor.
This is a recurrent question on this list.
> Is there a clean way to do this without removing the code from set.ml
> and modifying it?
Unfortunately, no.
Note that when duplicating the code from set.ml, you can either keep a
functorized code, with an additional type parameter:
module type OrderedType = sig
type 'a t
val compare: 'a t -> 'a t -> int
end
module type S = sig
type 'a elt
type 'a t
...
end
module Make(Ord: OrderedType): (S with type 'a elt = 'a Ord.t)
or directly substitute Pervasives.compare for the comparison function
to get a polymorphic data structure (and no functor anymore):
module AlphaSet : sig
type 'a elt
type 'a t
...
end
Best regards,
--
Jean-Christophe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-25 23:54 'a Set? Mike Hamburg
2005-01-26 8:25 ` [Caml-list] " Jean-Christophe Filliatre
@ 2005-01-26 9:13 ` Jon Harrop
2005-01-26 15:36 ` Frédéric Gava
1 sibling, 1 reply; 13+ messages in thread
From: Jon Harrop @ 2005-01-26 9:13 UTC (permalink / raw)
To: caml-list
On Tuesday 25 January 2005 23:54, Mike Hamburg wrote:
> Is there a clean way to do this without removing the code from set.ml
> and modifying it?
I do not believe so. I have also had to do this.
Compared to a flat set of functions, the functor approach has the advantage of
enforcing a consistently used compare function. The same effect can be
achieved with "elt = 'a" by writing a higher-order function which returns a
record containing the Set.* functions using the given function argument as
the compare function. Something equivalent to this:
type 'a t = 'a list
type 'a set =
{ empty : 'a t;
is_empty : 'a t -> bool;
add : 'a -> 'a t -> 'a t;
mem : 'a -> 'a t -> bool }
let rec add compare e = function
[] -> [e]
| h :: t -> match compare h e with
-1 -> e :: h :: t
| 0 -> e :: t
| _ -> h :: add compare e t
let rec mem compare e = function
[] -> false
| h :: t -> match compare h e with
-1 -> false
| 0 -> true
| _ -> mem compare e t
let make ?(compare=compare) () =
{ empty = [];
is_empty = (fun s -> s=[]);
add = add compare;
mem = mem compare }
Possible issues with this are that building closures (i.e. in "make") is
expensive and that the resulting type is monomorphic ('_a). You can probably
get a polymorphic type most easily by putting the definitions of "add" etc.
in the record definition, rather than partially applying their arguments.
Cheers,
Jon.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 8:25 ` [Caml-list] " Jean-Christophe Filliatre
@ 2005-01-26 10:13 ` Frédéric Gava
2005-01-26 11:04 ` Radu Grigore
0 siblings, 1 reply; 13+ messages in thread
From: Frédéric Gava @ 2005-01-26 10:13 UTC (permalink / raw)
Cc: caml-list
Hi
> Mike Hamburg writes:
> > Is there any clean way to make a type 'a set, corresponding to Set.Make
> > of a module with type t='a and compare=Pervasives.compare? I'm trying
> > to make a module which uses sets of arbitrary types of objects, and I
> > don't want to have to make it a functor.
>
> This is a recurrent question on this list.
>
> > Is there a clean way to do this without removing the code from set.ml
> > and modifying it?
>
> Unfortunately, no.
> Note that when duplicating the code from set.ml, you can either keep a
> functorized code, with an additional type parameter:
I think this problem comes from the stdlib of OCaml. We have:
1) For the Hashtable
type ('a, 'b) t
and
val length : ('a, 'b) t -> int
and
module type S = sig
type key
type 'a t
.... end
2) For the Map
module type S = sig
type key
type +'a t
end
3) For the Set
module type S = sig
type elt
type t
val cardinal : t -> int
end
This is hard to understand why the signatures of those modules are so
differents. Why there is (for example) not for the set, this signature:
module type S = sig
type 'a elt
type 'a t
...
end ?
Furthermore there is no lenght/cardinal function for the Map. Note that
WeakHashtble have the function val count : t -> int, so three different
names for the same things. When I teach Ocaml, many students are lost with
this differences.
Best regards,
Frédéric Gava
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 10:13 ` Frédéric Gava
@ 2005-01-26 11:04 ` Radu Grigore
2005-01-26 12:04 ` Jacques Garrigue
0 siblings, 1 reply; 13+ messages in thread
From: Radu Grigore @ 2005-01-26 11:04 UTC (permalink / raw)
To: caml-list
On Wed, 26 Jan 2005 11:13:58 +0100, Frédéric Gava
<frederic.gava@wanadoo.fr> wrote:
> When I teach Ocaml, many students are lost with
> this differences.
What puzzeled my is that List/String methods take the structure on
which they act as the first parameter while the Set/Map methods take
the structure on which they act as their last parameter. Is there a
reason?
--
regards,
radu
http://rgrig.idilis.ro/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 11:04 ` Radu Grigore
@ 2005-01-26 12:04 ` Jacques Garrigue
2005-01-26 16:00 ` Alex Baretta
2005-01-29 9:55 ` Radu Grigore
0 siblings, 2 replies; 13+ messages in thread
From: Jacques Garrigue @ 2005-01-26 12:04 UTC (permalink / raw)
To: radugrigore; +Cc: caml-list
From: Radu Grigore <radugrigore@gmail.com>
> On Wed, 26 Jan 2005 11:13:58 +0100, Frédéric Gava
> <frederic.gava@wanadoo.fr> wrote:
> > When I teach Ocaml, many students are lost with
> > this differences.
>
> What puzzeled my is that List/String methods take the structure on
> which they act as the first parameter while the Set/Map methods take
> the structure on which they act as their last parameter. Is there a
> reason?
There seems to be an habit of having side-effecting functions take
their "object" as first parameter, while side-effect-free functions
take them as last.
One reason is that it is natural to specialize side-effecting function
on their "object", as it doesn't change (only its contents do), while
effect-free functions are best seen as transforming their object
(which should be last).
If you respect this convention, the type tells you about the semantics
:-)
Jacques Garrigue
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 9:13 ` Jon Harrop
@ 2005-01-26 15:36 ` Frédéric Gava
2005-01-26 16:06 ` Jon Harrop
0 siblings, 1 reply; 13+ messages in thread
From: Frédéric Gava @ 2005-01-26 15:36 UTC (permalink / raw)
To: caml-list
Hi,
> Compared to a flat set of functions, the functor approach has the
advantage of
> enforcing a consistently used compare function.
Ok, I am agree. It is just a remark about coherence of names of functions
and
interfaces of the modules in the stdlib. There is many ModuleName.S
interfaces. Have the same names for functions that have the same semantics
seems (to me) a good things. (for example, have a function cardinal in the
module Map, even if we could implemented this with a fold; the cardinal
function of the Sets are could also be implemented with a fold)
>The same effect can be
> achieved with "elt = 'a" by writing a higher-order function which returns
a
> record containing the Set.* functions using the given function argument as
> the compare function. Something equivalent to this:
>
> type 'a t = 'a list
>....
> Cheers,
> Jon.
Ok. I am also agree. But the complexity is the problem of this data
structure ;-)
Cheers,
Frédéric Gava
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 12:04 ` Jacques Garrigue
@ 2005-01-26 16:00 ` Alex Baretta
2005-01-26 16:14 ` Jacques Carette
2005-01-26 21:09 ` Mike Hamburg
2005-01-29 9:55 ` Radu Grigore
1 sibling, 2 replies; 13+ messages in thread
From: Alex Baretta @ 2005-01-26 16:00 UTC (permalink / raw)
To: caml-list
Jacques Garrigue wrote:
> From: Radu Grigore <radugrigore@gmail.com>
> If you respect this convention, the type tells you about the semantics
> :-)
There are two different patterns for function signatures: the Hashtbl
pattern and the Map pattern. Both are "good", depending on the context.
Since I need both approaches I have come up with a little trick to get
the best of both worlds.
# let (~%) f = fun x y -> f y x
The ~% operator swaps the first and the second parameter in a function
call. The following is a trivial example of its use.
# ~% Printf.kprintf "Hello %s!" failwith "World";;
Exception: Failure "Hello World!".
Alex
--
*********************************************************************
http://www.barettadeit.com/
Baretta DE&IT
A division of Baretta SRL
tel. +39 02 370 111 55
fax. +39 02 370 111 54
Our technology:
The Application System/Xcaml (AS/Xcaml)
<http://www.asxcaml.org/>
The FreerP Project
<http://www.freerp.org/>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 15:36 ` Frédéric Gava
@ 2005-01-26 16:06 ` Jon Harrop
0 siblings, 0 replies; 13+ messages in thread
From: Jon Harrop @ 2005-01-26 16:06 UTC (permalink / raw)
To: caml-list
On Wednesday 26 January 2005 15:36, Frédéric Gava wrote:
> ...
> Ok, I am agree. It is just a remark about coherence of names of functions
> and
> interfaces of the modules in the stdlib. There is many ModuleName.S
> interfaces. Have the same names for functions that have the same semantics
> seems (to me) a good things. (for example, have a function cardinal in the
> module Map, even if we could implemented this with a fold; the cardinal
> function of the Sets are could also be implemented with a fold)
There are several problems with this. Firstly, the name "cardinal". A set has
cardinality. Lists and arrays have length. In C++ the equivalent function is
"size". Should a map use one of those names or something else (is a map a
_set_ of mappings? => "cardinal").
Secondly, there are numerous variants on a theme here. You suggest
implementing Map.cardinal with a fold => O(n). This may be the best that can
be done at the moment (assuming the internal representation stores maximum
depth but not number of elements) but by storing the number of elements in
all branches you could have O(1) "cardinal". Of course, there are other
variants too (e.g. min = max = d depth => 2^d - 1 elements).
Ultimately, the core library is maintained by INRIA who can ill-afford to
expend man-hours on adding arbitrary functionality to the core library. I
would love to see such inclusions (and many others).
Perhaps I should make a webpage listing useful things for people to dabble
on. :-)
Cheers,
Jon.
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [Caml-list] 'a Set?
2005-01-26 16:00 ` Alex Baretta
@ 2005-01-26 16:14 ` Jacques Carette
2005-01-26 21:09 ` Mike Hamburg
1 sibling, 0 replies; 13+ messages in thread
From: Jacques Carette @ 2005-01-26 16:14 UTC (permalink / raw)
To: 'Alex Baretta', caml-list
This (~%) operator is called 'flip' in Haskell, and it is used there all the
time. It is kind-of surprising that flip is not in Pervasives [as has been
mentionned before http://caml.inria.fr/archives/200106/msg00093.html].
Jacques
-----Original Message-----
From: caml-list-admin@yquem.inria.fr [mailto:caml-list-admin@yquem.inria.fr]
On Behalf Of Alex Baretta
Sent: January 26, 2005 11:00 AM
To: caml-list@inria.fr
Subject: Re: [Caml-list] 'a Set?
Jacques Garrigue wrote:
> From: Radu Grigore <radugrigore@gmail.com>
> If you respect this convention, the type tells you about the semantics
> :-)
There are two different patterns for function signatures: the Hashtbl
pattern and the Map pattern. Both are "good", depending on the context.
Since I need both approaches I have come up with a little trick to get
the best of both worlds.
# let (~%) f = fun x y -> f y x
The ~% operator swaps the first and the second parameter in a function
call. The following is a trivial example of its use.
# ~% Printf.kprintf "Hello %s!" failwith "World";;
Exception: Failure "Hello World!".
Alex
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 16:00 ` Alex Baretta
2005-01-26 16:14 ` Jacques Carette
@ 2005-01-26 21:09 ` Mike Hamburg
1 sibling, 0 replies; 13+ messages in thread
From: Mike Hamburg @ 2005-01-26 21:09 UTC (permalink / raw)
To: Alex Baretta; +Cc: caml-list
I call this operator <?>, because I often use it like so:
List.map (List.nth <?> 3) myList;;
Sadly, at toplevel <?> makes you lots of pretty '_a that restrict your
future actions. See my next post for questions about '_a.
Mike
On Jan 26, 2005, at 11:00 AM, Alex Baretta wrote:
> Jacques Garrigue wrote:
>> From: Radu Grigore <radugrigore@gmail.com>
>
>> If you respect this convention, the type tells you about the semantics
>> :-)
>
> There are two different patterns for function signatures: the Hashtbl
> pattern and the Map pattern. Both are "good", depending on the
> context. Since I need both approaches I have come up with a little
> trick to get the best of both worlds.
>
> # let (~%) f = fun x y -> f y x
>
> The ~% operator swaps the first and the second parameter in a function
> call. The following is a trivial example of its use.
>
> # ~% Printf.kprintf "Hello %s!" failwith "World";;
> Exception: Failure "Hello World!".
>
> Alex
>
> --
> *********************************************************************
> http://www.barettadeit.com/
> Baretta DE&IT
> A division of Baretta SRL
>
> tel. +39 02 370 111 55
> fax. +39 02 370 111 54
>
> Our technology:
>
> The Application System/Xcaml (AS/Xcaml)
> <http://www.asxcaml.org/>
>
> The FreerP Project
> <http://www.freerp.org/>
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] 'a Set?
2005-01-26 12:04 ` Jacques Garrigue
2005-01-26 16:00 ` Alex Baretta
@ 2005-01-29 9:55 ` Radu Grigore
1 sibling, 0 replies; 13+ messages in thread
From: Radu Grigore @ 2005-01-29 9:55 UTC (permalink / raw)
To: Jacques Garrigue; +Cc: caml-list
On Wed, 26 Jan 2005 21:04:00 +0900 (JST), Jacques Garrigue
<garrigue@math.nagoya-u.ac.jp> wrote:
> There seems to be an habit of having side-effecting functions take
> their "object" as first parameter, while side-effect-free functions
> take them as last.
This makes sense; but it does not seem to be respected by the standard
library. For example Queue does modifications in place and doesn't
take the queue as the first parameter. Another example is List.nth
which does not have side-effects but takes the list as the first
parameter. And I didn't even tried to look for examples that don't
follow your rule: I was more or less randomly browsing the manual.
> If you respect this convention, the type tells you about the semantics
> :-)
It is a good convention and I'll try follow it. Thanks.
--
regards,
radu
http://rgrig.idilis.ro/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 'a Set?
@ 2005-01-26 14:07 Jeff Shaw
0 siblings, 0 replies; 13+ messages in thread
From: Jeff Shaw @ 2005-01-26 14:07 UTC (permalink / raw)
To: hamburg; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 677 bytes --]
Mike,
I know of no way to do what you're asking for. However, you can always use lists as an ad hoc kind of set. Use List.mem to check membership, and some functions to add elements or create a set while looking for duplicates:
let add n list =
let rec aux = function
l::ls when compare l n = 0 -> list
| l::ls -> aux ls
| [] -> list @ [n]
in aux list
let create list =
let rec aux accumulator = function
l::ls -> aux (add l accumulator) ls
| [] -> accumulator
in aux [] list
This is terribly inefficient for big sets, but it works. It could be made more efficient by making sure the lists are ordered, etc.
Jeff
[-- Attachment #2: Type: text/html, Size: 1629 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2005-01-29 9:55 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-25 23:54 'a Set? Mike Hamburg
2005-01-26 8:25 ` [Caml-list] " Jean-Christophe Filliatre
2005-01-26 10:13 ` Frédéric Gava
2005-01-26 11:04 ` Radu Grigore
2005-01-26 12:04 ` Jacques Garrigue
2005-01-26 16:00 ` Alex Baretta
2005-01-26 16:14 ` Jacques Carette
2005-01-26 21:09 ` Mike Hamburg
2005-01-29 9:55 ` Radu Grigore
2005-01-26 9:13 ` Jon Harrop
2005-01-26 15:36 ` Frédéric Gava
2005-01-26 16:06 ` Jon Harrop
2005-01-26 14:07 Jeff Shaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox