我在使用类型约束的接口进行泛型操作时遇到了问题。
这是类型
type LeftistHeap<'a when 'a : comparison> =
...
interface IHeap<LeftistHeap<'a>, 'a> with
...
member this.Insert (x : 'a) = LeftistHeap.insert x this
和界面
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
此代码没有问题
let insertThruList l h =
List.fold (fun (h' : LeftistHeap<'a>) x -> h'.Insert x ) h l
但是如果我尝试对接口的代码进行分类
let insertThruList l h =
List.fold (fun (h' : IHeap<_,'a>) x -> h'.Insert x ) h l
我在h'Insert
时收到此错误类型不匹配。期待一个 “B
时,结果类型将是无限的
但给了一个 IHEAP&LT; 'B' A&GT;
统一''b'和'IHeap&lt;'b,'a&gt;'
答案 0 :(得分:4)
编译器的权利:您正在尝试使用'c
,而您需要IHeap<'c,_>
。从'c :> IHeap<'c,_>
开始,一种解决方案就是插入一个向上播放器:
let insertThruList l h =
List.fold (fun (h' : IHeap<_,_>) x -> h'.Insert x :> _) h l
或者,您可以指出您不希望输入(确切地)为IHeap<_,_>
,而是指某个特定的子类型:
let insertThruList l h =
List.fold (fun (h' : #IHeap<_,_>) x -> h'.Insert x) h l
这可能是你真正想要的(类型更具体)。这相当于更详细的定义:
let insertThruList<'c,'a when 'a : comparison and 'c :> IHeap<'c,'a>> l h =
List.fold (fun (h' : 'c) x -> h'.Insert x) h l
答案 1 :(得分:2)
这适合您的情况吗?
let insertThruList l (h : 'T when 'T :> IHeap<'T, 'a> ) =
List.fold (fun (h' : 'T) x -> h'.Insert x ) h l