我正在尝试为F#元组创建类型增强方法。这段代码可以很好地编译:

type System.Tuple<'a, 'b> with
    member this.ToParameter name =
        match this with
        | this -> sprintf "%s=%O,%O" name (this.Item1, this.Item2)

但是,当我尝试调用此方法时:
printfn "%s" (("cat", 2).ToParameter("test"))

我收到一条错误消息:“未定义此字段,构造函数或成员'ToParameter'。”在解释器中,以下表达式将它们的类型报告为System.Tuple'2的某种形式:
typedefof<'a * 'b>.FullName
(1, 2).GetType().FullName

在Visual Studio中,如果将鼠标悬停在表达式上:
let a = 1, 2

它报告int * int类型。当我尝试扩展此类型或它的通用等效项'a *'b时,出现错误。

是否可以为F#元组创建通用扩充?

最佳答案

您问题的答案与我对类似问题here给出的答案几乎相同。也就是说,类型扩展无法使用的原因是“System.Tuple<_,...,_>只是元组的编码形式,而不是编译器使用的静态表示形式。请参见规范中的6.3.2 Tuple Expressions。”

要使用类型扩展名,您必须先包装,然后转换元组值:

let tuple = box ("cat", 2) :?> System.Tuple<string,int>
printfn "%s" (tuple.ToParameter("test"))

另外:还请注意,您的类型扩展名中有一个轻微的语法错误,应该是:
type System.Tuple<'a, 'b> with
    member this.ToParameter name =
        match this with
        | this -> sprintf "%s=%O,%O" name this.Item1 this.Item2 //removed parens around Item1 and Item2

07-28 02:43
查看更多