功能签名在类型的一部分时不同(它不再是通用的)

时间:2013-09-12 09:20:57

标签: f#

为什么这些功能的签名不同?

此功能:

type a () = 
    member this.ThirdElementOfTupleFromListToSequence = function 
        | (q, w, ids) -> (q,w, (List.toSeq ids))

有这个签名:(obj * obj * obj list -> obj * obj * seq<obj>)

当我使用let分配相同的功能时:

let ThirdElementOfTupleFromListToSequence = function 
    | (q, w, ids) -> (q,w, (List.toSeq ids))

它有这个签名:('a* 'b * 'c list -> 'a * 'b * seq<'c>)

这两个功能都不在任何地方使用。

2 个答案:

答案 0 :(得分:10)

这里的问题是你没有定义一个方法,而是一个值恰好是一个函数的属性。在.NET中,属性不能是通用的。

为了使它成为一个方法,你需要在声明中明确它:

type a () =
    member this.ThirdElementOfTupleFromListToSequence(q, w, ids) =
        (q,w, (List.toSeq ids))

或者使其与原始版本更相似

type a () =
    member this.ThirdElementOfTupleFromListToSequence(arg) =
        match arg with
        | (q, w, ids) -> (q,w, (List.toSeq ids))

(请注意,这两个版本实际上是不同的 - 第一个是带有三个参数的方法,第二个是带有一个参数的方法,它是一个元组)。

答案 1 :(得分:3)

类型签名不同的原因是因为CLR不支持通用属性;见:Why does C# not allow generic properties?

在您的第一个示例中,编译器推断通用参数,就像它对let绑定示例一样,但它必须“填写”泛型参数,因为不允许创建泛型属性。编译器使用obj代替通用参数,因为这可以保证有效。