9

为什么这些函数的签名不同?

这个功能:

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>)

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

4

2 回答 2

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))

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

于 2013-09-12T09:49:27.350 回答
3

类型签名不同的原因是因为 CLR 不支持泛型属性;请参阅:为什么 C# 不允许泛型属性?

在您的第一个示例中,编译器推断泛型参数,就像它为let-bound 示例所做的那样,但它必须“填充”泛型参数,因为它不允许创建泛型属性。编译器使用obj通用参数代替泛型参数,因为这样可以保证工作。

于 2013-09-12T12:50:36.620 回答