title: Can an input parameter of an abstract type member be constrained in F#?
body: <p>Taking the idea of phantom types explained in this post <a href="https://stackoverflow.com/questions/3583679/implementing-phantom-types-in-f">Implementing phantom types in F#</a> , I'm trying to constrain the input parameter of an abstract type member, and more generally any type member. This may be impossible, and I'm happy to get that message.</p>
  
  <p>Here is what I am attempting:</p>
  
  <pre><code>// my phantom type
  type Ascending = interface end
  type Descending = interface end
  type HeapOrder =
      inherit Ascending
      inherit Descending
  
  // my type
  type IHeap&lt;'a when 'a : comparison&gt; =
      inherit System.Collections.IEnumerable
      inherit System.Collections.Generic.IEnumerable&lt;'a&gt;
  ...
  abstract member Order : HeapOrder with get
  ...
  // ...and one or the other of these inherited types :
  type IHeap&lt;'c, 'a when 'c :&gt; IHeap&lt;'c, 'a&gt; and 'a : comparison&gt; =
      inherit IHeap&lt;'a&gt;
  // or:
  type IHeap&lt;'a, 'd when 'a : comparison  and 'd :&gt; HeapOrder&gt; =
      inherit System.Collections.IEnumerable
      inherit System.Collections.Generic.IEnumerable&lt;'a&gt;
  
  type IHeap&lt;'c, 'a, 'd when 'c :&gt; IHeap&lt;'c, 'a, 'd&gt; and 'a : comparison and 'd :&gt; HeapOrder&gt; =
      inherit IHeap&lt;'a&gt;
  ...
  // ...and the member I want to constrain, so that the HeapOrder of the 
  // input parameter matches the HeapOrder of the instantiated type.
  // Conceptually one of these alternatives (none of these build, 
  // but they should convey what I'm attempting):
  //
  abstract member Merge : ('c when 'c&lt;'c, 'a&gt; : (member Order when Order :&gt; 'd))
  // or
  abstract member Merge : ('c when c' :&gt; IHeap&lt;'c, 'a, 'd&gt;) -&gt; 'c
  // or
  abstract member Merge : ('c when c' : #IHeap&lt;'c, 'a, 'd&gt;) -&gt; 'c
  </code></pre>