From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p2JJEXVo026085 for ; Sat, 19 Mar 2011 20:14:33 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsIBAFedhE3RVdY0kGdsb2JhbACERKEpCBQBAQEBCQkNBxQEIYhNnySKBjyCH4QvL4hbAQEDBYEig0V3BIxnhEOEPDo X-IronPort-AV: E=Sophos;i="4.63,211,1299452400"; d="scan'208";a="103092707" Received: from mail-bw0-f52.google.com ([209.85.214.52]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 19 Mar 2011 20:14:28 +0100 Received: by bwj24 with SMTP id 24so5398088bwj.39 for ; Sat, 19 Mar 2011 12:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; bh=CjpLpIAYobH0YJ+x9aXqC+/e8TdfUTZxyWkxEgurY7Q=; b=ZM6dDYLqO1gkfUkelkXL14qy13dsSi2osYKC4FN6xDhe2Xo0QlD7qklhSacHg8zD82 CuN5vMZeTAJPvSypDC2peXwneCwg2XK8korHTBUKkxGwMi/Y4WKdfaDsMCd1ihKvvEhW W2U0HpZr2VhDqftWMzeho2pgH+W3EG0IWmbQc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:user-agent:cc:references:in-reply-to :mime-version:content-type:content-transfer-encoding:message-id; b=dfWdjKW59eg2jgruf8djO6a/B+g+TPu67Yq4kZ9eKK/ZVong5YxRSc6HplUkMrZAJu DFqrSx5WfohPxMt6NF6EoakUqxSM8NKWT/UG4X9jh8AI3ODj6zTTbZheG7oqzaClTRgU apqK/yPURaoOG/4GZ7yiAtWBDvZwFxRfE4lX8= Received: by 10.204.84.5 with SMTP id h5mr2046571bkl.201.1300562067638; Sat, 19 Mar 2011 12:14:27 -0700 (PDT) Received: from cloudy.localnet ([85.69.95.49]) by mx.google.com with ESMTPS id q18sm3093562bka.15.2011.03.19.12.14.23 (version=SSLv3 cipher=OTHER); Sat, 19 Mar 2011 12:14:26 -0700 (PDT) From: Raphael Proust To: Guillaume Yziquel Date: Sat, 19 Mar 2011 20:20:36 +0100 User-Agent: KMail/1.13.6 (Linux/2.6.37-ARCH; KDE/4.6.1; i686; ; ) Cc: caml-list@yquem.inria.fr References: <201103191648.40345.raphlalou@gmail.com> <20110319174803.GP20405@localhost> In-Reply-To: <20110319174803.GP20405@localhost> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Message-Id: <201103192020.36314.raphlalou@gmail.com> Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p2JJEXVo026085 Subject: Re: [Caml-list] Recursive Parametric class type Typing 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