From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.4 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 1E351BC6B for ; Wed, 28 Feb 2007 01:23:15 +0100 (CET) Received: from kurims.kurims.kyoto-u.ac.jp (kurims.kurims.kyoto-u.ac.jp [130.54.16.1]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l1S0NCEw026934 for ; Wed, 28 Feb 2007 01:23:14 +0100 Received: from localhost (orion [130.54.16.5]) by kurims.kurims.kyoto-u.ac.jp (8.13.7/8.13.7) with ESMTP id l1S0N9E6017214; Wed, 28 Feb 2007 09:23:09 +0900 (JST) Date: Wed, 28 Feb 2007 09:23:06 +0900 (JST) Message-Id: <20070228.092306.92341518.garrigue@math.nagoya-u.ac.jp> To: geoff.romer@gmail.com Cc: caml-list@inria.fr Subject: Re: [Caml-list] Fwd: "ocaml_beginners"::[] Trouble combining polymorphic classes and polymorphic methods From: Jacques Garrigue In-Reply-To: <301730110702271322m72d20cffh37bddb14dc91b6f9@mail.gmail.com> References: <301730110702251747y72ae9fbdqd33bd8d08293cbe3@mail.gmail.com> <301730110702271322m72d20cffh37bddb14dc91b6f9@mail.gmail.com> X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at discorde with ID 45E4CB70.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; ocaml:01 ocaml:01 foo:01 foo:01 escapes:01 recursive:01 recursion:01 sig:01 recursive:01 polymorphic:01 polymorphic:01 beginners:01 beginners:01 arbitrary:01 rec:01 From: "Geoffrey Romer" > [escalated from ocaml_beginners, where I got no response] > > I'm trying to create a polymorphic class 'a foo which has a > polymorphic method that takes as a parameter another foo object, but > one with arbitrary type. In other words, something like this: > > class virtual ['a] foo = > object (self) > method virtual bar : 'b. 'b foo -> unit > end;; > > When I try to compile this, though, I get a warning that I "cannot > quantify 'b because it escapes this scope". When I drop the " 'b. " it > compiles fine, but the reported type for bar is 'a foo -> unit; i.e. > it's no longer polymorphic. > > Is there a problem with trying to make a method polymorphic with > respect to the class type in this way? How can I make this work? The reason it does not work is that recursive object types have to be regular. That is, when using foo inside its own definition, the parameters must be the same. Since 'a <> 'b, this fails. This restriction is due to the structural typing of objects, and as such it does not apply to records, which are nominal. So you can write: type 'a foo = { bar : 'b. 'b foo -> unit; } which has basically the same meaning. You can also mix classes and records: type 'a foo_t = unit> and 'b foo_r = {foo: 'b foo_t} This way, you only need to wrap foo objects in foo_r when you want to pass them to bar. If you want to define a class type rather than an object type (class types are more versatile), you can use the following trick to create a recursion between a class type and a normal type; module rec M : sig class type ['a] foo = object method get : 'a method bar : 'b. 'b M.foo_r -> unit end type 'a foo_r = {foo: 'a foo} end = M You cannot define your virtual class directly inside the recursive module, because it would require an implementation, but this can be done easily afterwards: # class virtual ['a] foo = object (_ : 'a #M.foo) end;; class virtual ['a] foo : object method virtual bar : 'b M.foo_r -> unit method virtual get : 'a end Hope this helps. Jacques Garrigue