F#构造函数不接受元组?

LLS*_*LLS 10 f# constructor tuples

我尝试使用元组来创建F#中定义的类的新实例.为了复制问题,我尝试了以下代码.

type test(x: int, y:int) =
    let distance =
        x * x + y * y |> float |> sqrt
    new (x: int, y:int, z:int) =
        new test(x, y)
let args = 1, 2
let test2 = new test(args)
Run Code Online (Sandbox Code Playgroud)

它抱怨说

错误1成员或对象构造函数'test'不带1个参数.发现过载有2个参数.

如果我删除非默认构造函数,一切都很好.我不明白为什么它变成两个/三个参数而不是元组.

非常感谢你.

ild*_*arn 5

可能有一种更简单的语法来实现这一点,但我不知道它是什么:

type Test(tup : int*int) =
    let x, y = tup
    let distance =
        x * x + y * y |> float |> sqrt
    new (tup : int*int*int) =
        let x, y, _ = tup
        new Test((x, y))

let args1 = 1, 2
let test1 = new Test(args1)

let args2 = 3, 4, 5
let test2 = new Test(args2)
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 3

这很微妙,但根据规范。这是我挖出的一封旧电子邮件回复,其中有人问了类似的问题:

\n\n

...

\n\n

实际上,“元组”(在 F# 语言中)和“语法元组”(在 F# 规范中)之间也存在(微妙的)差异。

\n\n

当存在重载时,方法应用程序解析会有所不同。如果没有,则不会将参数(即方法调用中 ( 和 ) 之间指定的“东西”)分解为元组形式,因此编译器很高兴并说“哦,好吧,MyClass 的 ctor 需要1 个参数(一个元组),我看到 1 个参数(代码中的“元组”),所以我\xe2\x80\x99 将使用它”。

\n\n

然而,当你有 2 个重载时,上面的规则不再适用,编译器将尝试将参数分解为元组形式(在你的情况下,这将解析为:“哦,好吧,有 1 个参数,它是元组。但是等等,我有 2 个重载。并且您的参数列表(一个元素,元组)与任一参数列表都不匹配,因此出现错误消息“

\n\n

至少,\xe2\x80\x99 是我对F# 规范第 14.4 节的解释。

\n

  • @Brian - 我想这可能是因为构造函数参数成为字段,在这种情况下,所以值得更明确地了解它们的定义方式。但我仍然感觉不太对劲。 (3认同)
  • 在这种情况下,编译器不会将构造函数参数视为元组,我对此并不感到惊讶,但令我感到非常惊讶的是,您不能在构造函数绑定中使用模式,即 `type Test( (x, y) ) = ... `(或任何其他模式)。这有什么理由吗? (2认同)
  • 我是通过电子邮件询问的;很高兴我不是唯一一个觉得这令人困惑的人!使用方法重载也会遇到同样的问题(构造函数被视为方法)。 (2认同)