2011-07-09 10 views
9

Intenté usar una tupla para crear una nueva instancia de una clase definida en F #. Para duplicar el problema, probé el siguiente código.F # constructor no acepta tuplas?

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) 

Se queja de que

de error 1 El miembro o el objeto 'prueba' constructor no toma 1 argumento (s). Se encontró una sobrecarga teniendo 2 argumentos.

Si elimino el constructor no predeterminado, todo está bien. No entiendo por qué se convierte en dos/tres argumentos en lugar de tuplas.

Muchas gracias.

Respuesta

3

Esta es sutil, pero por la especificación. Aquí está una vieja respuesta por correo electrónico Desenterré en la que alguien hizo una pregunta similar:

...

en el juego, también hay (sutil) diferencia entre "tuplas" (en el # lenguaje F) y "tuplas sintácticas "(en la especificación F #).

La resolución de la aplicación del método es diferente cuando hay sobrecargas. Si no hay ninguno, la descomposición del argumento (es decir, el "material" especificado entre (y) en su invocación de método) a una forma de tupla no ocurre, entonces el compilador está contento y dice "oh ok, el código para MyClass toma 1 argumento (una tupla) y estoy viendo 1 argumento ("tupla" en tu código) así que lo usaré ".

Considerando que, cuando tiene 2 sobrecargas, entonces la regla anterior ya no se aplica y el compilador intentará descomponer el argumento en una forma de tupla (que en su caso se resolvería de la siguiente manera: "Oh, bien, hay 1 argumento que es tupla. Pero espera, tengo 2 sobrecargas. Y tu lista de argumentos (un elemento, tupla) no coincide con ninguna lista de argumentos, de ahí el mensaje de error "

Al menos, esa es mi interpretación del F# specification, sección 14.4.

+2

No me sorprendió que el compilador no trate el constructo o argumento como una tupla en este caso, pero estaba bastante sorprendido de que no pueda usar patrones en el enlace del constructor, es decir, 'escriba Test ((x, y)) = ...' (o cualquier otro patrón). ¿Hay alguna razón para eso? –

+0

Buena pregunta, no sé. – Brian

+0

Muchas gracias. F # es realmente confuso en algunos aspectos. – LLS

5

Puede haber una sintaxis más fácil de conseguir este trabajo, pero no saben lo que es:

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

Gracias. Había pensado que los argumentos múltiples en un par de paréntesis son los mismos que las tuplas. – LLS