* beginner question: DAGs w/ recursive types an encapsulation of a Map
@ 2007-05-04 23:46 Justin Corn
2007-05-05 0:59 ` [Caml-list] " Gabriel Kerneis
2007-05-05 7:10 ` Jean-Christophe Filliatre
0 siblings, 2 replies; 7+ messages in thread
From: Justin Corn @ 2007-05-04 23:46 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 805 bytes --]
Dear all,
I'm trying to construct a tree (for the Aho-Corasick exact match algorithm)
but I can't quite figure out how to do this.
1) Is it possible to declare a recursive type that would allow for a tree
having an arbitrarily large number of children per node?
I couldn't figure that one out, so I was thinking I could use a Map
collection to represent edges.
2) How do you wrap a Map in an object or record? In my case the edges
represent single characters, so I started with
#module CharMap = Map.Make(Char);;
but then the top level was not happy with
#type node = { a: int; b: CharMap.t };;
3) If there are preexisting graphical libraries for ocaml, maybe I should
just use those, but after searching a bit I was unable to find any. Does
someone know where I could find one?
Thanks,
Justin
[-- Attachment #2: Type: text/html, Size: 891 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-04 23:46 beginner question: DAGs w/ recursive types an encapsulation of a Map Justin Corn
@ 2007-05-05 0:59 ` Gabriel Kerneis
2007-05-06 3:33 ` Pablo Polvorin
2007-05-05 7:10 ` Jean-Christophe Filliatre
1 sibling, 1 reply; 7+ messages in thread
From: Gabriel Kerneis @ 2007-05-05 0:59 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 2986 bytes --]
Le Fri, 4 May 2007 16:46:29 -0700, "Justin Corn" <justincorn@gmail.com>
a écrit :
> 1) Is it possible to declare a recursive type that would allow for a
> tree having an arbitrarily large number of children per node?
Yes.
> I couldn't figure that one out, so I was thinking I could use a Map
> collection to represent edges.
For example, using association lists :
# type tree = Leaf of int | Node of int * (char * node) list ;;
type tree = Leaf of int | Node of int * (char * node) list
# Node (2,[('a',Leaf 5)]);;
- : tree = Node (2, [('a', Leaf 5)])
Or even :
# type tree' = int * (char * tree') list ;;
type tree' = int * (char * tree') list
# let t : tree' = (2,[('a',(5,[]))]);;
val t : tree' = (2, [('a', (5, []))])
The second solution involves recursive types : you must run 'ocaml
-rectypes' to use it. It could be unsafe and shouldn't be used unless
you're perfectly aware of what you're doing.
> 2) How do you wrap a Map in an object or record? In my case the edges
> represent single characters, so I started with
>
> #module CharMap = Map.Make(Char);;
Good idea : lists are not very efficient, so the solution shown above
will be greatly improved using Maps (especially if you've got a large
number of edges).
> but then the top level was not happy with
>
> #type node = { a: int; b: CharMap.t };;
The type constructor CharMap.t expects 1 argument(s),
but is here applied to 0 argument(s)
Map expects an argument : Char is the type of the key (as you can see
on the type, when you create CharMap[1] ), but you must define the
type of the values. Here, you want to store nodes, so :
#type node = { a: int; b: node CharMap.t };;
If you prefer a generic node type, you can do :
# type 'a node = { a: int; b: 'a CharMap.t };;
(this is a just an example of how keeping things generic - here, it's
totally useless)
> 3) If there are preexisting graphical libraries for ocaml, maybe I
> should just use those, but after searching a bit I was unable to find
> any. Does someone know where I could find one?
Depends on what you want to do. Have a look at the Caml Hump [2].
[1]
# module CharMap = Map.Make(Char);;
module CharMap :
sig
type key = Char.t (*type of the keys = Char.t*)
type 'a t = 'a Map.Make(Char).t (*type of the values relies on 'a*)
val empty : 'a t
val is_empty : 'a t -> bool
val add : key -> 'a -> 'a t -> 'a t
val find : key -> 'a t -> 'a
val remove : key -> 'a t -> 'a t
val mem : key -> 'a t -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
end
[2] http://caml.inria.fr/cgi-bin/hump.cgi
Regards,
--
Gabriel Kerneis
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-04 23:46 beginner question: DAGs w/ recursive types an encapsulation of a Map Justin Corn
2007-05-05 0:59 ` [Caml-list] " Gabriel Kerneis
@ 2007-05-05 7:10 ` Jean-Christophe Filliatre
1 sibling, 0 replies; 7+ messages in thread
From: Jean-Christophe Filliatre @ 2007-05-05 7:10 UTC (permalink / raw)
To: Justin Corn; +Cc: caml-list
> 3) If there are preexisting graphical libraries for ocaml, maybe I should
> just use those, but after searching a bit I was unable to find any. Does
> someone know where I could find one?
There is a (small but portable) graphical library coming with
ocaml. This is the Graphics module, documented in the manual:
http://caml.inria.fr/pub/docs/manual-ocaml/manual039.html
--
Jean-Christophe
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-05 0:59 ` [Caml-list] " Gabriel Kerneis
@ 2007-05-06 3:33 ` Pablo Polvorin
2007-05-06 3:39 ` Jon Harrop
0 siblings, 1 reply; 7+ messages in thread
From: Pablo Polvorin @ 2007-05-06 3:33 UTC (permalink / raw)
To: Gabriel Kerneis; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 3890 bytes --]
Sorry, may be a stupid question, but i dont get it.
What is the difference between the first and second solution that you
propose, that make the second less safe?.
As far as i understand, both are recursive type declarations. I do read some
post related to this topic.. but fail to fully understand it.
what i missing here?
Sorry for the
2007/5/5, Gabriel Kerneis <gabriel.kerneis@enst.fr>:
>
> Le Fri, 4 May 2007 16:46:29 -0700, "Justin Corn" <justincorn@gmail.com>
> a écrit :
> > 1) Is it possible to declare a recursive type that would allow for a
> > tree having an arbitrarily large number of children per node?
>
> Yes.
>
> > I couldn't figure that one out, so I was thinking I could use a Map
> > collection to represent edges.
>
> For example, using association lists :
> # type tree = Leaf of int | Node of int * (char * node) list ;;
> type tree = Leaf of int | Node of int * (char * node) list
> # Node (2,[('a',Leaf 5)]);;
> - : tree = Node (2, [('a', Leaf 5)])
>
> Or even :
>
> # type tree' = int * (char * tree') list ;;
> type tree' = int * (char * tree') list
> # let t : tree' = (2,[('a',(5,[]))]);;
> val t : tree' = (2, [('a', (5, []))])
>
> The second solution involves recursive types : you must run 'ocaml
> -rectypes' to use it. It could be unsafe and shouldn't be used unless
> you're perfectly aware of what you're doing.
>
> > 2) How do you wrap a Map in an object or record? In my case the edges
> > represent single characters, so I started with
> >
> > #module CharMap = Map.Make(Char);;
>
> Good idea : lists are not very efficient, so the solution shown above
> will be greatly improved using Maps (especially if you've got a large
> number of edges).
>
> > but then the top level was not happy with
> >
> > #type node = { a: int; b: CharMap.t };;
> The type constructor CharMap.t expects 1 argument(s),
> but is here applied to 0 argument(s)
>
> Map expects an argument : Char is the type of the key (as you can see
> on the type, when you create CharMap[1] ), but you must define the
> type of the values. Here, you want to store nodes, so :
> #type node = { a: int; b: node CharMap.t };;
>
> If you prefer a generic node type, you can do :
> # type 'a node = { a: int; b: 'a CharMap.t };;
> (this is a just an example of how keeping things generic - here, it's
> totally useless)
>
> > 3) If there are preexisting graphical libraries for ocaml, maybe I
> > should just use those, but after searching a bit I was unable to find
> > any. Does someone know where I could find one?
>
> Depends on what you want to do. Have a look at the Caml Hump [2].
>
>
> [1]
> # module CharMap = Map.Make(Char);;
> module CharMap :
> sig
> type key = Char.t (*type of the keys = Char.t*)
> type 'a t = 'a Map.Make(Char).t (*type of the values relies on 'a*)
> val empty : 'a t
> val is_empty : 'a t -> bool
> val add : key -> 'a -> 'a t -> 'a t
> val find : key -> 'a t -> 'a
> val remove : key -> 'a t -> 'a t
> val mem : key -> 'a t -> bool
> val iter : (key -> 'a -> unit) -> 'a t -> unit
> val map : ('a -> 'b) -> 'a t -> 'b t
> val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
> val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
> val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
> val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
> end
>
> [2] http://caml.inria.fr/cgi-bin/hump.cgi
>
> Regards,
> --
> Gabriel Kerneis
>
>
> _______________________________________________
> 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
>
>
>
--
Pablo Polvorin
[-- Attachment #2: Type: text/html, Size: 5880 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-06 3:33 ` Pablo Polvorin
@ 2007-05-06 3:39 ` Jon Harrop
2007-05-06 7:54 ` Alain Frisch
0 siblings, 1 reply; 7+ messages in thread
From: Jon Harrop @ 2007-05-06 3:39 UTC (permalink / raw)
To: caml-list
On Sunday 06 May 2007 04:33, Pablo Polvorin wrote:
> Sorry, may be a stupid question, but i dont get it.
> What is the difference between the first and second solution that you
> propose, that make the second less safe?.
> As far as i understand, both are recursive type declarations. I do read
> some post related to this topic.. but fail to fully understand it.
> what i missing here?
OCaml has a -rectypes option that relaxes type checking and allows more types
though. This relaxation is usually undesirable because it results in
obfuscated error messages for some type errors, so -rectypes is off by
default.
However, you have struck upon a case where it could be useful.
Rather than defining your tree type as:
# type tree = Node of int * (char * tree) list ;;
type tree = Node of int * (char * tree) list
with -rectypes you can define it as:
# type tree' = int * (char * tree') list ;;
type tree' = int * (char * tree') list
This is not "unsafe" in the usual sense of the word but it means that the
compiler will be less friendly on all of the rest of your code. Also, I have
had the OCaml compilers crash in the past if you try to mix code compiled
with -rectypes with code without.
Another solution is to use polymorphic variants:
# let rec tree = `Node(3, ['a', tree]);;
val tree : [> `Node of int * (char * 'a) list ] as 'a = ...
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-06 3:39 ` Jon Harrop
@ 2007-05-06 7:54 ` Alain Frisch
2007-05-06 8:05 ` skaller
0 siblings, 1 reply; 7+ messages in thread
From: Alain Frisch @ 2007-05-06 7:54 UTC (permalink / raw)
To: Jon Harrop; +Cc: caml-list
Jon Harrop wrote:
> # type tree' = int * (char * tree') list ;;
> type tree' = int * (char * tree') list
>
> This is not "unsafe" in the usual sense of the word but it means that the
> compiler will be less friendly on all of the rest of your code.
The declaration is not "unsafe" by itself, but the -rectypes option is,
in the sense that it will make the compiler accept programs that will
produce infinite loops in the run-time system:
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lazy.html
<< Note: if the program is compiled with the -rectypes option,
ill-founded recursive definitions of the form let rec x = lazy x or let
rec x = lazy(lazy(...(lazy x))) are accepted by the type-checker and
lead, when forced, to ill-formed values that trigger infinite loops in
the garbage collector and other parts of the run-time system. Without
the -rectypes option, such ill-founded recursive definitions are
rejected by the type-checker. >>
(One might argue that the type checker does not reject non-terminating
programs anyway.)
-- Alain
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] beginner question: DAGs w/ recursive types an encapsulation of a Map
2007-05-06 7:54 ` Alain Frisch
@ 2007-05-06 8:05 ` skaller
0 siblings, 0 replies; 7+ messages in thread
From: skaller @ 2007-05-06 8:05 UTC (permalink / raw)
To: Alain Frisch; +Cc: Jon Harrop, caml-list
On Sun, 2007-05-06 at 09:54 +0200, Alain Frisch wrote:
> Jon Harrop wrote:
> << Note: if the program is compiled with the -rectypes option,
> ill-founded recursive definitions of the form let rec x = lazy x or let
> rec x = lazy(lazy(...(lazy x))) are accepted by the type-checker and
> lead, when forced, to ill-formed values that trigger infinite loops in
> the garbage collector and other parts of the run-time system.
I'm curious how this can happen to the garbage collector?
Recursive routines that don't maintain a visitation trace
I can understand failing .. but surely the GC has to deal
with cycles anyhow.. I mean the whole *point* of a garbage
collector is to deal with cyclic data .. :)
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-05-06 8:05 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-04 23:46 beginner question: DAGs w/ recursive types an encapsulation of a Map Justin Corn
2007-05-05 0:59 ` [Caml-list] " Gabriel Kerneis
2007-05-06 3:33 ` Pablo Polvorin
2007-05-06 3:39 ` Jon Harrop
2007-05-06 7:54 ` Alain Frisch
2007-05-06 8:05 ` skaller
2007-05-05 7:10 ` Jean-Christophe Filliatre
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox