3

我在获取具有类型约束的接口以正常工作时遇到问题。

这是类型

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<'b,'a>
当统一 ''b' 和 'IHeap<'b,'a>' 时,结果类型将是无限的

4

2 回答 2

4

编译器是对的:您试图'c在需要IHeap<'c,_>. 由于'c :> IHeap<'c,_>,一种解决方案就是插入一个向上转换:

let insertThruList l h =
    List.fold (fun (h' : IHeap<_,_>) x -> h'.Insert  x :> _) h l

或者,您可以表明您不希望输入(完全)是 an 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
于 2012-11-05T18:35:46.460 回答
2

这对你的情况有用吗?

let insertThruList l (h : 'T when 'T :> IHeap<'T, 'a> )  =
    List.fold (fun (h' : 'T) x -> h'.Insert  x  ) h l
于 2012-11-05T18:36:05.980 回答