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
> 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
>
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)
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.
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