泛型 – 在组合泛型和非泛型类时,类型变量转义范围

我在F#中有一个带有单个类型参数的泛型类,并且想要创建一个包含工厂方法的静态类.当我编写类时,F#编译器会生成与“转换其范围的类型变量”相关的错误.我的问题是为什么错误存在以及如何解决它.

我创建了一个最小尺寸代码片段来演示此问题:

type Foo<'a>(element : 'a) =

    member this.Copy () = Bar.Create(element)

and Bar =

    static member Create(element : 'a) = new Foo<'a>(element)

类型中的相互递归是因为我喜欢类型Foo<'a>能够在静态类中调用工厂方法.上面的代码片段没有编译,错误是:“类型推断导致类型变量a逃避其范围.考虑添加显式类型参数声明或调整代码以减少通用.”该错误被注册为位于Bar类的Create方法中.不幸的是,我并不是真的了解这个问题,也不知道如何解决它.有任何想法吗?

这是另外一个观察.片段

type Foo<'a>(element : 'a) =

    member this.Element = element

and Bar =

    static member Create(element : 'a) = new Foo<'a>(element)

编译.因此,该问题似乎与基于Foo< a>的Copy()方法进行的类型推断有关.类.此外,该片段

type Foo<'a>(element : 'a) =

    member this.Copy () = Bar.Create(element)

and Bar =

    static member Create<'a>(element) = new Foo<'a>(element)

是一个更像C#的代码版本(其中静态方法明确地是通用的),它也没有编译,错误“这段代码不够通用.类型变量’a不能一概而论,因为它会逃避其范围.“

最佳答案
递归成员的类型推断通常需要至少对某些定义进行类型注释.但是,有时您可以通过重新排序定义来避免这种情况,至少可以在简化的复制中使用:

type Bar = 
    static member Create(element) = Foo(element)
and Foo<'a>(element:'a) =
    member this.Copy() = Bar.Create(element)

(请注意,我甚至删除了Bar.Create中元素的注释).

不幸的是,我不知道在任何特定情况下都会有一个易于理解的解释.

转载注明原文:泛型 – 在组合泛型和非泛型类时,类型变量转义范围 - 代码日志