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=1.9 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE, SPF_NEUTRAL autolearn=disabled version=3.1.3 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 13460BBAF for ; Tue, 21 Apr 2009 10:51:00 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhcDAKEl7UnVBJXykWdsb2JhbACBTpRwAQEBAQkJDAcPvFuDfQY X-IronPort-AV: E=Sophos;i="4.38,431,1233529200"; d="scan'208";a="28017817" Received: from outmailhost.telefonica.net (HELO ctsmtpout1.frontal.correo) ([213.4.149.242]) by mail1-smtp-roc.national.inria.fr with ESMTP; 21 Apr 2009 10:50:59 +0200 Received: from NANA.localdomain (88.0.113.211) by ctsmtpout1.frontal.correo (7.2.056.6) (authenticated as ferferse$telefonica.net) id 49E648FB000E7065; Tue, 21 Apr 2009 10:50:27 +0200 Received: from mfp by NANA.localdomain with local (Exim 4.69) (envelope-from ) id 1LwBgQ-0001c4-KQ; Tue, 21 Apr 2009 10:50:26 +0200 Date: Tue, 21 Apr 2009 10:50:26 +0200 From: Mauricio Fernandez To: eliot@colba.net, caml-list@inria.fr Subject: Re: [Caml-list] Polymorphism problem Message-ID: <20090421085026.GH8986@NANA.localdomain> Mail-Followup-To: eliot@colba.net, caml-list@inria.fr References: <200904202215.27735.jon@ffconsultancy.com> <49ED2516.9030103@colba.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <49ED2516.9030103@colba.net> User-Agent: Mutt/1.5.17+20080114 (2008-01-14) X-Spam: no; 0.00; polymorphism:01 recursion:01 ocaml:01 recursive:01 polymorphism:01 sig:01 val:01 struct:01 sig:01 val:01 20,:98 2009:98 polymorphic:01 polymorphic:01 wrote:01 On Mon, Apr 20, 2009 at 09:44:54PM -0400, Eliot Handelman wrote: > Consider this: > > type 'a x = { x_v : 'a } > > and 'a y = { y_x : int kind; > y_arr : 'a array > } > and 'a kind = > X of 'a x > | Y of 'a y > > > I'd like to write a function _getter_ that's polymorphic over kind. This > doesn't work, getting int kind -> int: > > let rec getter = function > X x -> x.x_v > | Y y -> y.y_arr.(getter y.y_x) > > which seems surprising to me since getter y.y_x is an intermediate > value that's never returned. Is this just a limitation of the type system or > does this result make sense? The above function requires polymorphic recursion, which OCaml doesn't support directly. There are several ways to encode it, though, one involving recursive modules and another rank-2 polymorphism: # module rec M : sig val getter : 'a kind -> 'a end = struct let getter = function X x -> x.x_v | Y y -> y.y_arr.(M.getter y.y_x) end;; module rec M : sig val getter : 'a kind -> 'a end # M.getter;; - : 'a kind -> 'a = # type get = { get : 'a. 'a kind -> 'a };; type get = { get : 'a. 'a kind -> 'a; } # let rec get = { get = function X x -> x.x_v | Y y -> y.y_arr.(get.get y.y_x) };; val get : get = {get = } # let getter = get.get;; val getter : 'a kind -> 'a = -- Mauricio Fernandez - http://eigenclass.org