Taking the idea of phantom types explained in this post Implementing phantom types in F# , 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.
Here is what I am attempting:
// my phantom type
type Ascending = interface end
type Descending = interface end
type HeapOrder =
inherit Ascending
inherit Descending
// my type
type IHeap<'a when 'a : comparison> =
inherit System.Collections.IEnumerable
inherit System.Collections.Generic.IEnumerable<'a>
...
abstract member Order : HeapOrder with get
...
// ...and one or the other of these inherited types :
type IHeap<'c, 'a when 'c :> IHeap<'c, 'a> and 'a : comparison> =
inherit IHeap<'a>
// or:
type IHeap<'a, 'd when 'a : comparison and 'd :> HeapOrder> =
inherit System.Collections.IEnumerable
inherit System.Collections.Generic.IEnumerable<'a>
type IHeap<'c, 'a, 'd when 'c :> IHeap<'c, 'a, 'd> and 'a : comparison and 'd :> HeapOrder> =
inherit IHeap<'a>
...
// ...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<'c, 'a> : (member Order when Order :> 'd))
// or
abstract member Merge : ('c when c' :> IHeap<'c, 'a, 'd>) -> 'c
// or
abstract member Merge : ('c when c' : #IHeap<'c, 'a, 'd>) -> 'c