caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <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
Date: Wed, 28 Feb 2007 09:23:06 +0900 (JST)	[thread overview]
Message-ID: <20070228.092306.92341518.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <301730110702271322m72d20cffh37bddb14dc91b6f9@mail.gmail.com>

From: "Geoffrey Romer" <geoff.romer@gmail.com>
> [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 = <get : 'a; bar : 'b. 'b foo_r -> 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


  reply	other threads:[~2007-02-28  0:23 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <301730110702251747y72ae9fbdqd33bd8d08293cbe3@mail.gmail.com>
2007-02-27 21:22 ` Geoffrey Romer
2007-02-28  0:23   ` Jacques Garrigue [this message]
2007-02-28  1:18     ` [Caml-list] " Lukasz Stafiniak
2007-02-28  1:34       ` Jacques Garrigue
2007-02-28  1:57         ` skaller
2007-02-28  3:23           ` Daniel Bünzli
2007-02-28  4:01             ` Jacques Garrigue
2007-02-28  5:09               ` skaller
2007-02-28 13:47               ` Daniel Bünzli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070228.092306.92341518.garrigue@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=geoff.romer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).