Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] mutually dependent class and type

8 views
Skip to first unread message

Sébastien Hinderer

unread,
Sep 25, 2008, 6:24:53 PM9/25/08
to caml...@yquem.inria.fr
Dear list,

Is there a (clean) way to define simultaneously a class and a type that
are mutually recursive ?
Something like this :
class element (c : content) =
object
...
end and type content =
| Data of string
| Elements of element list;;

This is of course not a valid OCaml definition, but is there a way to
express it ?

Many thanks in advance for your help,
Sébastien.

_______________________________________________
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

Martin Jambon

unread,
Sep 25, 2008, 7:48:29 PM9/25/08
to Sébastien Hinderer, caml...@yquem.inria.fr
On Fri, 26 Sep 2008, Sébastien Hinderer wrote:

> Dear list,
>
> Is there a (clean) way to define simultaneously a class and a type that
> are mutually recursive ?

I don't think so, but you don't have to.

> Something like this :
> class element (c : content) =
> object
> ...
> end and type content =
> | Data of string
> | Elements of element list;;
>
> This is of course not a valid OCaml definition, but is there a way to
> express it ?

With each class comes a type of the same name. Such type can also be
defined independently from the notion of class. It is syntactically like
a record with angle brackets:

type element =
< content : content >

and content =


Data of string
| Elements of element list;;

class element_class (c : content) =
object
method content = c
end


# new element_class (Elements [ new element_class (Data "abc") ]);;
- : element_class = <obj>


Martin

> Many thanks in advance for your help,
> Sébastien.
>
> _______________________________________________
> 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
>

--
http://mjambon.com/

Jeff Shaw

unread,
Sep 25, 2008, 8:04:04 PM9/25/08
to caml...@inria.fr
I don't know how you might directly get what you want, but here's one
way to get an equivalent result.

class element_aux (c : [`Data of string | `Element of element list]) =
object end

type content = Data of string | Element of element list;;

let content_of_variant = function Data d -> `Data d | Element e ->
`Element e

class element (c : content) = element_aux (content_of_variant c)

Jeff Shaw

unread,
Sep 25, 2008, 8:08:38 PM9/25/08
to caml...@inria.fr
I'm more sick than I thought. content_of_variant should have been
variant_of_content, and I forgot to delete the double redundant semi-colon.

Tim Rentsch

unread,
Sep 26, 2008, 2:41:49 AM9/26/08
to Sebastien...@ens-lyon.org, caml...@yquem.inria.fr
> Date: Fri, 26 Sep 2008 00:24:39 +0200
> From: =?iso-8859-1?Q?S=E9bastien?= Hinderer <Sebastien...@ens-lyon.org>

>
> Is there a (clean) way to define simultaneously a class and a type that
> are mutually recursive ?
> Something like this :
> class element (c : content) =
> object
> ...
> end and type content =
> | Data of string
> | Elements of element list;;
>
> This is of course not a valid OCaml definition, but is there a way to
> express it ?

Frequently a good way around such problems is to abstract the type
definition with respect to the mutually dependent defined item.
Then, supply the appropriate parameter when defining the class:

type 'a generic_content =
| Data of string
| Elements of 'a list

class element (c : element generic_content) =
object
method c_value = c
end

Voila! The class is defined in terms of a type that depends on
the class.

For classes, this technique produces a nicer result if applied to
a class type rather than a class directly. Then we can define
the desired type 'content' appropriately and use it in the
class definition:

type 'a generic_content =
| Data of string
| Elements of 'a list

class type element_t =
object
method c_value : element_t generic_content
end

type content = element_t generic_content

class element (c : content) =
object

method c_value = c
end

This technique of parameterizing a type definition with
respect to a dependent type is a good one to know; it
also is sometimes useful with modules/functors.

Yann Régis-Gianas

unread,
Oct 5, 2008, 9:31:46 AM10/5/08
to caml...@yquem.inria.fr
Hello Sebastien,

you can use recursive module:

module rec I : sig
class element : I.content -> object end


type content =
| Data of string

| Elements of I.element list
end = struct
class element (c : I.content) = object end


type content =
| Data of string

| Elements of I.element list
end

Best regards,

--
Yann Régis-Gianas

0 new messages