F# 函数签名在';s类型的一部分(它不再是泛型)

F# 函数签名在';s类型的一部分(它不再是泛型),f#,F#,为什么这些函数的签名不同 此功能: type a () = member this.ThirdElementOfTupleFromListToSequence = function | (q, w, ids) -> (q,w, (List.toSeq ids)) 有此签名:(obj*obj*obj列表->obj*obj*seq) 当我使用分配相同的函数时,让: let ThirdElementOfTupleFromListToSequence = functi

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

此功能:

type a () = 
    member this.ThirdElementOfTupleFromListToSequence = function 
        | (q, w, ids) -> (q,w, (List.toSeq ids))
有此签名:
(obj*obj*obj列表->obj*obj*seq)

当我使用
分配相同的函数时,让

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

它有这样一个签名:
('a*'b*'c list->'a*'b*seq这里的问题是您没有定义一个方法,而是定义一个值恰好是函数的属性。在.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))

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

类型签名不同的原因是因为CLR不支持泛型属性;请参阅:


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

Wow如果我见过抽象,这是一个泄漏的情况。因此,函数模式匹配语法在不同情况下使用时返回不同的内容?您可以n通过将类型设置为泛型来解决这个问题。阿尔贝詹:不完全是这样。其思想是泛型表达式实际上有无限多个类型。例如,
id
有类型
'a->'a
,因此它也有类型
int->int
obj->obj
('a->'b)>('a->'b)
等。当在给定上下文中使用泛型表达式时,上下文中的某些约束可能会限制类型。例如,在
ID2
中,
id
的类型因参数而被约束为
int->int
。这里也会发生同样的现象:函数的类型因事实而受到约束它会影响一个属性的值。这一切都是从这里开始的,我读到
将x与|
匹配和
函数|
是一样的。但这并不是字面上说的。他们可能会强调你在使用函数时创建了lambda。我同意,关于
函数
k的文档是有意义的需要注意的是,它相当于
fun x->match x with
。它实际上是这样说的:“前面语法中显示的模式匹配函数相当于下面的函数。”但这一段不是很清楚。