* [Caml-list] Recursive Parametric class type Typing
@ 2011-03-19 15:48 Raphael Proust
2011-03-19 17:48 ` Guillaume Yziquel
2011-03-19 20:02 ` Philippe Strauss
0 siblings, 2 replies; 6+ messages in thread
From: Raphael Proust @ 2011-03-19 15:48 UTC (permalink / raw)
To: caml-list
Hi list,
Trying to bind a javascript library for js_of_ocaml, I encountered the following
pattern (here drastically simplified):
class type ['t] c =
object
method plus: 't -> unit
method minus: unit -> 't
method container: unit -> container
end
and container =
object
method int: unit -> int c
method string: unit -> string c
end
The following error is raised at compile time:
Error: This type string should be an instance of type int
In the use case:
- instead of [int] and [string] there are six different [class type]s;
- [classe type]s have more methods; and
- there are additional recursive [class type]s
Why is there such a limitation on the types? Is there a work around that
wouldn't induce (too much) code duplication?
Thanks,
--
______________
Raphaël Proust
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Recursive Parametric class type Typing
2011-03-19 15:48 [Caml-list] Recursive Parametric class type Typing Raphael Proust
@ 2011-03-19 17:48 ` Guillaume Yziquel
2011-03-19 19:20 ` Raphael Proust
2011-03-19 20:02 ` Philippe Strauss
1 sibling, 1 reply; 6+ messages in thread
From: Guillaume Yziquel @ 2011-03-19 17:48 UTC (permalink / raw)
To: Raphael Proust; +Cc: caml-list
Le Saturday 19 Mar 2011 à 16:48:40 (+0100), Raphael Proust a écrit :
> Hi list,
>
> Trying to bind a javascript library for js_of_ocaml, I encountered the following
> pattern (here drastically simplified):
>
> class type ['t] c =
> object
> method plus: 't -> unit
> method minus: unit -> 't
> method container: unit -> container
> end
> and container =
> object
> method int: unit -> int c
> method string: unit -> string c
> end
>
> The following error is raised at compile time:
> Error: This type string should be an instance of type int
>
> In the use case:
> - instead of [int] and [string] there are six different [class type]s;
> - [classe type]s have more methods; and
> - there are additional recursive [class type]s
>
> Why is there such a limitation on the types? Is there a work around that
> wouldn't induce (too much) code duplication?
The reason why there is this behaviour is unification within the 'and'
declaration. method int says that 't in ['t] c is of type int,
therefore it should also be an int c in method string instead of a
string c.
Workaround: Use recursive modules. They are a solution for keeping
recursion while breaking type unification. Something in the taste of:
yziquel@seldon:~$ ocaml
Objective Caml version 3.12.0
# module rec Q : sig
class type ['w] e = object method r : 'w end
end = struct
class type t = object
method z : int Q.e
method u : string Q.e
end
class type ['w] e = object method r : 'w end
end;;
module rec Q : sig class type ['a] e = object method r : 'a end end
Not sure if this fits your bill when it comes to avoiding code
duplication.
--
Guillaume Yziquel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Recursive Parametric class type Typing
2011-03-19 17:48 ` Guillaume Yziquel
@ 2011-03-19 19:20 ` Raphael Proust
2011-03-19 19:45 ` Guillaume Yziquel
0 siblings, 1 reply; 6+ messages in thread
From: Raphael Proust @ 2011-03-19 19:20 UTC (permalink / raw)
To: Guillaume Yziquel; +Cc: caml-list
Le samedi 19 mars 2011 18:48:03, Guillaume Yziquel a écrit :
> Le Saturday 19 Mar 2011 à 16:48:40 (+0100), Raphael Proust a écrit :
> > Hi list,
> >
> > Trying to bind a javascript library for js_of_ocaml, I encountered the
> > following pattern (here drastically simplified):
> >
> > class type ['t] c =
> > object
> > method plus: 't -> unit
> > method minus: unit -> 't
> > method container: unit -> container
> > end
> > and container =
> > object
> > method int: unit -> int c
> > method string: unit -> string c
> > end
> >
> > The following error is raised at compile time:
> > Error: This type string should be an instance of type int
> >
> > In the use case:
> > - instead of [int] and [string] there are six different [class type]s;
> > - [classe type]s have more methods; and
> > - there are additional recursive [class type]s
> >
> > Why is there such a limitation on the types? Is there a work around that
> > wouldn't induce (too much) code duplication?
>
> The reason why there is this behaviour is unification within the 'and'
> declaration. method int says that 't in ['t] c is of type int,
> therefore it should also be an int c in method string instead of a
> string c.
It makes sens…
>
> Workaround: Use recursive modules. They are a solution for keeping
> recursion while breaking type unification. Something in the taste of:
>
> yziquel@seldon:~$ ocaml
> Objective Caml version 3.12.0
>
> # module rec Q : sig
> class type ['w] e = object method r : 'w end
> end = struct
> class type t = object
> method z : int Q.e
> method u : string Q.e
> end
> class type ['w] e = object method r : 'w end
> end;;
> module rec Q : sig class type ['a] e = object method r : 'a end end
>
> Not sure if this fits your bill when it comes to avoiding code
> duplication.
Because I want both [t] and [e] available (in fact there are 4 recursive classes
I want available), I made several recursive modules. Beside having each type
written twice, it still had a typing error:
Error: In the definition of Paper.paper, type
Svg.circle_attr Elem.element
should be
'a Elem.element
I found a (half satisfying) workaround using the fact that methods that makes
parametrization necessary and methods that makes recursivity necessary do not
intersect. So I ended up with a parametric class that is not part of the
recursion. The "polymorphic recursion" of sort is broken but I need a different
class for each type I want to instantiate the type with.
--
______________
Raphaël Proust
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Recursive Parametric class type Typing
2011-03-19 19:20 ` Raphael Proust
@ 2011-03-19 19:45 ` Guillaume Yziquel
2011-03-19 20:36 ` Raphael Proust
0 siblings, 1 reply; 6+ messages in thread
From: Guillaume Yziquel @ 2011-03-19 19:45 UTC (permalink / raw)
To: Raphael Proust; +Cc: caml-list
Le Saturday 19 Mar 2011 à 20:20:36 (+0100), Raphael Proust a écrit :
> Le samedi 19 mars 2011 18:48:03, Guillaume Yziquel a écrit :
> > Le Saturday 19 Mar 2011 à 16:48:40 (+0100), Raphael Proust a écrit :
> > > Hi list,
> > >
> > > Trying to bind a javascript library for js_of_ocaml, I encountered the
> > > following pattern (here drastically simplified):
> > >
> > > class type ['t] c =
> > > object
> > > method plus: 't -> unit
> > > method minus: unit -> 't
> > > method container: unit -> container
> > > end
> > > and container =
> > > object
> > > method int: unit -> int c
> > > method string: unit -> string c
> > > end
> > >
> > > The following error is raised at compile time:
> > > Error: This type string should be an instance of type int
> > >
> > > In the use case:
> > > - instead of [int] and [string] there are six different [class type]s;
> > > - [classe type]s have more methods; and
> > > - there are additional recursive [class type]s
> > >
> > > Why is there such a limitation on the types? Is there a work around that
> > > wouldn't induce (too much) code duplication?
> >
> > The reason why there is this behaviour is unification within the 'and'
> > declaration. method int says that 't in ['t] c is of type int,
> > therefore it should also be an int c in method string instead of a
> > string c.
>
> It makes sens…
>
> >
> > Workaround: Use recursive modules. They are a solution for keeping
> > recursion while breaking type unification. Something in the taste of:
> >
> > yziquel@seldon:~$ ocaml
> > Objective Caml version 3.12.0
> >
> > # module rec Q : sig
> > class type ['w] e = object method r : 'w end
> > end = struct
> > class type t = object
> > method z : int Q.e
> > method u : string Q.e
> > end
> > class type ['w] e = object method r : 'w end
> > end;;
> > module rec Q : sig class type ['a] e = object method r : 'a end end
> >
> > Not sure if this fits your bill when it comes to avoiding code
> > duplication.
>
> Because I want both [t] and [e] available (in fact there are 4 recursive classes
> I want available), I made several recursive modules. Beside having each type
> written twice, it still had a typing error:
>
> Error: In the definition of Paper.paper, type
> Svg.circle_attr Elem.element
> should be
> 'a Elem.element
Noticed it too. Do not know where that comes from.
> I found a (half satisfying) workaround using the fact that methods that makes
> parametrization necessary and methods that makes recursivity necessary do not
> intersect. So I ended up with a parametric class that is not part of the
> recursion. The "polymorphic recursion" of sort is broken but I need a different
> class for each type I want to instantiate the type with.
A perhaps more natural way would be to use object types. Something like
type t = private < z : int e; u : string e >
is easier to declare, and easier to declare recursively. Drawbacks: you
still have issues when you want to declare the meat of your classes; and
doesn't work well with ocamldoc.
--
Guillaume Yziquel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Recursive Parametric class type Typing
2011-03-19 15:48 [Caml-list] Recursive Parametric class type Typing Raphael Proust
2011-03-19 17:48 ` Guillaume Yziquel
@ 2011-03-19 20:02 ` Philippe Strauss
1 sibling, 0 replies; 6+ messages in thread
From: Philippe Strauss @ 2011-03-19 20:02 UTC (permalink / raw)
To: caml-list; +Cc: Raphael Proust
Jacques answered me about a parametrized class prob. I had some time ago, about an important restriction:
"Object types are allowed to be recursive, but they are restricted to _regular_ types,
where recursive occurences have identical type parameters.
In particular, this means that in the above line, ('a,'b) node_virt_t and ('b,'c) node_virt_t
must have the same parameters, i.e. that 'a = 'b and 'b = 'c, i.e. all your types
end up being identical."
(maybe an FAQ is somewhat missing on the main, inria, ocaml website about that kind of infos.?)
Le 19 mars 2011 à 16:48, Raphael Proust a écrit :
> Hi list,
>
> Trying to bind a javascript library for js_of_ocaml, I encountered the following
> pattern (here drastically simplified):
>
> class type ['t] c =
> object
> method plus: 't -> unit
> method minus: unit -> 't
> method container: unit -> container
> end
> and container =
> object
> method int: unit -> int c
> method string: unit -> string c
> end
>
> The following error is raised at compile time:
> Error: This type string should be an instance of type int
>
> In the use case:
> - instead of [int] and [string] there are six different [class type]s;
> - [classe type]s have more methods; and
> - there are additional recursive [class type]s
>
>
> Why is there such a limitation on the types? Is there a work around that
> wouldn't induce (too much) code duplication?
>
> Thanks,
> --
> ______________
> Raphaël Proust
>
>
> --
> Caml-list mailing list. Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Recursive Parametric class type Typing
2011-03-19 19:45 ` Guillaume Yziquel
@ 2011-03-19 20:36 ` Raphael Proust
0 siblings, 0 replies; 6+ messages in thread
From: Raphael Proust @ 2011-03-19 20:36 UTC (permalink / raw)
To: Guillaume Yziquel; +Cc: caml-list
Le samedi 19 mars 2011 20:45:33, Guillaume Yziquel a écrit :
> Le Saturday 19 Mar 2011 à 20:20:36 (+0100), Raphael Proust a écrit :
> > Le samedi 19 mars 2011 18:48:03, Guillaume Yziquel a écrit :
> > > Le Saturday 19 Mar 2011 à 16:48:40 (+0100), Raphael Proust a écrit :
> > > > Hi list,
> > > >
> > > > Trying to bind a javascript library for js_of_ocaml, I encountered
> > > > the following pattern (here drastically simplified):
> > > >
> > > > class type ['t] c =
> > > > object
> > > > method plus: 't -> unit
> > > > method minus: unit -> 't
> > > > method container: unit -> container
> > > > end
> > > > and container =
> > > > object
> > > > method int: unit -> int c
> > > > method string: unit -> string c
> > > > end
> > > >
> > > > The following error is raised at compile time:
> > > > Error: This type string should be an instance of type int
> > > >
> > > > In the use case:
> > > > - instead of [int] and [string] there are six different [class
> > > > type]s; - [classe type]s have more methods; and
> > > > - there are additional recursive [class type]s
> > > >
> > > > Why is there such a limitation on the types? Is there a work around
> > > > that wouldn't induce (too much) code duplication?
> > >
> > > The reason why there is this behaviour is unification within the 'and'
> > > declaration. method int says that 't in ['t] c is of type int,
> > > therefore it should also be an int c in method string instead of a
> > > string c.
> >
> > It makes sens…
> >
> > > Workaround: Use recursive modules. They are a solution for keeping
> > > recursion while breaking type unification. Something in the taste of:
> > >
> > > yziquel@seldon:~$ ocaml
> > > […]
> >
> > Because I want both [t] and [e] available (in fact there are 4 recursive
> > classes I want available), I made several recursive modules. Beside
> > having each type written twice, it still had a typing error:
> >
> > Error: In the definition of Paper.paper, type
> >
> > Svg.circle_attr Elem.element
> > should be
> > 'a Elem.element
>
> Noticed it too. Do not know where that comes from.
>
> > […]
>
> A perhaps more natural way would be to use object types. Something like
>
> type t = private < z : int e; u : string e >
>
> is easier to declare, and easier to declare recursively. Drawbacks: you
> still have issues when you want to declare the meat of your classes; and
> doesn't work well with ocamldoc.
Well my classes don't have meat: they only serve as cast from js objects (sort
of…).
I used this approach (save the [private] inducing an Error about types not
having a row variable) and it works. I just have to duplicate a few things due
to inheritance not being available.
Thanks,
--
______________
Raphaël Proust
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-03-19 20:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-19 15:48 [Caml-list] Recursive Parametric class type Typing Raphael Proust
2011-03-19 17:48 ` Guillaume Yziquel
2011-03-19 19:20 ` Raphael Proust
2011-03-19 19:45 ` Guillaume Yziquel
2011-03-19 20:36 ` Raphael Proust
2011-03-19 20:02 ` Philippe Strauss
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox