统一时类型约束为无限的f#接口

时间:2012-11-05 17:56:15

标签: f#

我在使用类型约束的接口进行泛型操作时遇到了问题。

这是类型

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;'

时,结果类型将是无限的

2 个答案:

答案 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