I tried to use a tuple to create a new instance of a class defined in F#. To duplicate the problem, I tried the following code.
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)
It complains that
Error 1 The member or object constructor 'test' does not take 1 argument(s). An overload was found taking 2 arguments.
If I remove the non-default constructor, things are fine. I don't understand why it becomes two/three arguments instead of tuples.
Thank you very much.
There may be an easier syntax to get this working, but I don't know what it is:
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)
This is subtle, but per the spec. Here's an old email response I dug up where someone asked a similar question:
...
At play, there is also (subtle) difference between "tuples" (in the F# language) and "syntactic tuples" (in the F# specification).
Method application resolution is different when there are overloads. If there are none, the decomposition of the argument (i.e. the "stuff" specified between ( and ) in your method invocation) to a tuple form does not happen, so the compiler is happy and say "oh ok, the ctor for MyClass takes 1 argument (a tuple) and I am seeing 1 argument ("tuple" in your code) so I’ll use that".
Whereas, when you have 2 overloads, then the rule above does not apply anymore and the compiler will try to decompose the argument to a tuple form (which in your case would resolve in something like: "Oh ok, there is 1 argument which is tuple. But wait, I have 2 overloads. And your list of argument (one element, tuple) does not match either an argument list, hence the error message"
At least, that’s my interpretation of the F# specification, section 14.4.
精彩评论