title: Why the unbound type variables in OCAML object do not appear when class type is used?
body: <p>I'd like to understand the reason for this behavior of OCAML objects. Suppose I have a class <code>A</code> that calls methods of an object of another class <code>B</code>. Schematically, A#f calls B#g and B#h. The normal practice in OOP is that I would like to avoid using B as a fixed concrete class, but instead declare only an interface for B. What is the best way to do this in OCAML? I tried several options, and I do not quite understand the reason why some of them work while others don't. Here are the code samples.</p>
  
  <p>Version 1:</p>
  
  <pre><code> # class classA = object
      method f b = b#g + b#h 
     end ;;
   Error: Some type variables are unbound in this type:
       class a : object method f : &lt; g : int; h : int; .. &gt; -&gt; int end
     The method f has type (&lt; g : int; h : int; .. &gt; as 'a) -&gt; int where 'a
     is unbound
  </code></pre>
  
  <p>This behavior is well-known: OCAML correctly infers that <code>b</code> has the open object type <code>&lt;g:int;h:int;..&gt;</code> but then complains that my class does not declare any type variables. So it seems that <code>classA</code> is <em>required</em> to have type variables; I then introduced a type variable explicitly.</p>
  
  <p>Version 2:</p>
  
  <pre><code> # class ['a] classA2 = object
     method f (b:'a) = b#g + b#h
     end ;;
   class ['a] classA2 :
     object constraint 'a = &lt; g : int; h : int; .. &gt; method f : 'a -&gt; int end
  </code></pre>
  
  <p>This works, but the class is now explicitly polymorphic with a type constraint, as OCAML shows. It is also confusing that the class type contains a type variable <code>'a</code>, and yet I can still say <code>let x = new classA2</code> without specifying a type value for <code>'a</code>. Why is that possible?</p>
  
  <p>Another drawback of <code>classA2</code> is that an explicit type constraint <code>(b:'a)</code> contains a type variable. After all, I know that <code>b</code> must conform to a fixed interface rather than to an unknown type <code>'a</code>. I want OCAML to verify that this interface is indeed correct.</p>
  
  <p>So in version 3 I first declared an interface <code>classB</code> as a class type and then declared that <code>b</code> must be of this type:</p>
  
  <pre><code> # class type classB = object method g:int method h:int end;;
   class type classB = object method g : int method h : int end
   # class classA3 = object method f (b:classB) = b#g + b#h end;;
   class classA3 : object method f : classB -&gt; int end
  </code></pre>
  
  <p>This works too, but my puzzlement remains: why doesn't <code>classA3</code> require explicit polymorphism any more?</p>
  
  <p>Summary of questions:</p>
  
  <ul>
  <li>Why is it possible to use <code>new classA2</code> without specifying a type for <code>'a</code> even though <code>classA2</code> is declared with a type variable <code>'a</code>?</li>
  <li>Why does <code>classA3</code> accept a type constraint <code>(b:classB)</code> and does not require a bound type variable any more?</li>
  <li>Is the functionality of <code>classA2</code> and <code>classA3</code> different in some subtle way, and if yes, how?</li>
  </ul>