将管道元组转发到具有可选参数的方法

forward pipe tuple to a method with optional params

我得到了这样一段代码:

type x() =
    member x.f(number:int, ?text:string) =
        "doesn't matter"

let instance = new x()
let result = instance.f(1, "s")

这工作正常,但当我进行一些重构时我发现,以下甚至无法编译。

let param = (1,"s")
let result2 = param |> instance.f

错误信息是Type constraint mismatch. The type int * string is not compatible with type int The type 'int * string' is not compatible with the type 'int'

如果 f() 方法的两个参数都不是可选的,则第二个示例可以正常工作。

在我的真实代码中,这个元组更大(5 个值)并且由单独的函数计算。我该如何处理?

(我把LinqPad中的这个例子上传到http://share.linqpad.net/cu92w2.linq

问题是 instance.f 并不是真正的 first-class F# 句法函数。它更像是一个标准的 .NET 方法调用,因此由于一些与互操作性相关的设计决策,它的行为方式并不完全相同。这些差异在方法(但不是函数)独有的特性(例如重载)和本例中的可选参数的存在下变得明显。

如果将其包装到函数中,它将按预期工作:

let callf (a, b) = instance.f (a, b)
let param = (1,"s")
let result2 = param |> callf

当然现在这个函数没有可选参数,可选参数解析是在函数定义时做出的。