I’m having problems getting an interface with type constraints to work generically.
Here’s the type
type LeftistHeap<'a when 'a : comparison> =
...
interface IHeap<LeftistHeap<'a>, 'a> with
...
member this.Insert (x : 'a) = LeftistHeap.insert x this
and the interface
type IHeap<'a when 'a : comparison> =
inherit System.Collections.IEnumerable
inherit System.Collections.Generic.IEnumerable<'a>
...
type IHeap<'c, 'a when 'c :> IHeap<'c, 'a> and 'a : comparison> =
inherit IHeap<'a>
...
abstract member Insert : 'a -> 'c
this code works no problem
let insertThruList l h =
List.fold (fun (h' : LeftistHeap<'a>) x -> h'.Insert x ) h l
but if I try to genralize the code for the interface
let insertThruList l h =
List.fold (fun (h' : IHeap<_,'a>) x -> h'.Insert x ) h l
I get this error at h’.Insert
Type mismatch. Expecting a
‘b
but given a
IHeap<‘b,’a>
The resulting type would be infinite when unifying ”b’ and ‘IHeap<‘b,’a>’
The compiler’s right: you’re trying to use a
'cwhere you need anIHeap<'c,_>. Since'c :> IHeap<'c,_>, one solution is just to insert an upcast:Alternatively, you can indicate that you don’t want the input to be (exactly) an
IHeap<_,_>, but instead some particular subtype:This is probably what you really want (the type is more specific). This is equivalent to the more verbose definition: