caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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;
as well as URLs for NNTP newsgroup(s).