【问题标题】:f# interface with type constraint infinite when unifyingf# 统一时类型约束无限的接口
【发布时间】:2012-11-06 02:36:05
【问题描述】:

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

这是类型

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' 和 'IHeap'

时,结果类型将是无限的

【问题讨论】:

    标签: f#


    【解决方案1】:

    编译器是对的:您尝试在需要IHeap&lt;'c,_&gt; 的地方使用'c。由于'c :&gt; IHeap&lt;'c,_&gt;,一种解决方案就是插入一个向上转换:

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

    或者,您可以表明您不希望输入是(完全)IHeap&lt;_,_&gt;,而是某个特定的子类型:

    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
    

    【讨论】:

    • 灵活的类型指示器来拯救。 List.fold (fun (h' : #IHeap<_>) x -> h'.Insert x ) h l 谢谢!
    • 继续下一个问题。当约束类型接口是元组的一部分时,这似乎不起作用。示例:(fun (x : (#IHeap<_> * 'a list)) -> 同“infinte when unifying”问题。
    • @Jack - 你能举一个更完整的例子吗?我不明白为什么那行不通。
    • 我正准备制作一个简化的项目来复制该问题。应该尽快完成(排除太多中断)。
    • 我将问题隔离为拆箱问题 let x1 = box (tuple l) let x2 : #IHeap<_>> * list = unbox x1 ...and #为类型推断变量应用默认类型 'IHeap' 时,IHeap,_> 以错误 2 类型约束不匹配突出显示。当统一 ''a' 和 'IHeap' 时,结果类型将是无限的 考虑添加更多类型约束
    【解决方案2】:

    这对您的情况有用吗?

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

    【讨论】:

      猜你喜欢
      • 2016-11-16
      • 1970-01-01
      • 2014-08-20
      • 2016-11-13
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多