2011-07-09 138 views
9

我试图用元组来创建一个在F#中定义的类的新实例。为了复制这个问题,我尝试了下面的代码。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) 

它抱怨

错误1构件或物体 构造 '测试' 不采取1个 参数(一个或多个)。发现一个超载 需要2个参数。

如果我删除非默认的构造函数,事情没有问题。 我不明白为什么它变成2/3参数而不是元组。

非常感谢。

回答

3

这是很微妙的,但每个规范。下面是我挖出来的地方有人问过类似的问题的旧电子邮件回应:

...

在游戏中,也“元组”(在F#语言)和“句法元组之间(细微)的区别“(在F#规范中)。

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

然而,当你有2个重载时,那么上面的规则就不再适用了,编译器会尝试将参数分解为一个元组形式(在你的情况下,它会像下面这样解析:“哦,好的,有1参数是元组,但是等待,我有2个重载,而你的参数列表(一个元素,元组)与参数列表不匹配,因此错误消息“

至少,这是我对F# specification,section 14.4。

+2

我并不感到惊讶,因为编译器没有处理构造或参数作为一个元组,但是我很惊讶你不能在构造函数绑定中使用模式,即'type Test((x,y))= ...'(或任何其他模式)。这有什么理由吗? –

+0

好问题,我不知道。 – Brian

+0

非常感谢。 F#在某些方面确实令人困惑。 – LLS

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

谢谢。我曾想过一对括号中的多个参数与元组相同。 – LLS