F#类型推断不如类型注释所指示的通用

时间:2015-02-26 17:02:39

标签: generics f# type-inference

在以下代码段的最后一行中,我收到两条警告:This construct causes code to be less generic than indicated by the type annotations. The type variable 'c has been constrained to be type ''a'.This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a * 'a'.

type SomeBaseClass<'a> () =
    class end

type SomeClass<'a when 'a:equality> (getValue:unit->'a, ?arg2:SomeBaseClass<'b>) =
    inherit SomeBaseClass<'a*'a>()

    member this.Value with get () = getValue ()

    member this.Transform (transformation:'a->'c) =
        let func ():'c = transformation this.Value
        SomeClass<'c> (func, this) // warnings are attached to this line

另一方面,这可以毫无问题地编译:

type SomeOtherClass<'a when 'a:equality> (getValue:unit->'a) =
    inherit SomeBaseClass<'a*'a>()

    member this.Value with get () = getValue ()

    member this.Transform (transformation:'a->'c) =
        let func ():'c = transformation this.Value
        SomeOtherClass<'c> func

我没有看到任何阻止transformation返回不同于传递的类型的内容。我也不明白为什么第二个警告甚至是警告,因为显然我的目的是让新实例的'b类型参数为'a*'a

我在这里做错了什么?

1 个答案:

答案 0 :(得分:4)

泛型类型SomeClass在其定义中缺少的构造函数中使用泛型参数'b。将类型定义更改为

type SomeClass<'a, 'b when 'a:equality> ...

和警告

的行
    SomeClass(func, this)

删除错误,返回的类的类型为SomeClass<'c, ('a * 'a)>

我不知道这是怎么想的,所以我不知道这是否是一个明智的修正。