Una llamada a la función habitual en F # se escribe sin paréntesis y los parámetros están separados por espacios. La forma más sencilla de definir una función de varios parámetros es escribir esto:
let add a b = a + b
Como se señaló Pascal, esta forma de parámetros que especifican se llama currificación - la idea es que una función toma un solo parámetro y el resultado es una función que toma el segundo parámetro y devuelve el resultado real (u otra función). Al llamar a una función simple como esta, escribiría add 10 5
y el compilador (en principio) interpreta esto como ((add 10) 5)
. Esto tiene algunas ventajas agradables - por ejemplo, que le permite utilizar aplicación de función parcial donde se especifica sólo unos primeros argumentos de una función:
let addTen = add 10 // declares function that adds 10 to any argument
addTen 5 // returns 15
addTen 9 // returns 19
Esta característica es útil en la práctica, por ejemplo, en el tratamiento de listas:
// The code using explicit lambda functions..
[ 1 .. 10 ] |> List.map (fun x -> add 10 x)
// Can be rewritten using partial function application:
[ 1 .. 10 ] |> List.map (add 10)
Ahora, vamos a la parte confusa - en F #, también puedes trabajar con tuplas, que son tipos de datos simples que te permiten agrupar múltiples valores en valores individuales (ten en cuenta que las tuplas no están relacionadas con funciones de cualquier manera).Por ejemplo, puede escribir:
let tup = (10, "ten") // creating a tuple
let (n, s) = tup // extracting elements of a tuple using pattern
printfn "n=%d s=%s" n s // prints "n=10 s=ten"
Cuando se escribe una función que toma los parámetros entre paréntesis, separados por una coma, en realidad estás escribiendo una función que toma un único parámetro que es una tupla:
// The following function:
let add (a, b) = a * b
// ...means exactly the same thing as:
let add tup =
let (a, b) = tup // extract elements of a tuple
a * b
// You can call the function by creating tuple inline:
add (10, 5)
// .. or by creating tuple in advance
let t = (10, 5)
add t
Esta es una función de un tipo diferente - toma un solo parámetro que es una tupla, mientras que la primera versión era una función que tomaba dos parámetros (usando currying).
En F #, la situación es un poco más complicada que eso: los métodos .NET aparecen como métodos que toman una tupla como parámetro (para que pueda llamarlos con la notación entre paréntesis), pero son algo limitados (por ejemplo, no se puede crear una tupla primero y luego llamar al método dándole solo la tupla). Además, el código F # compilado en realidad no produce métodos en la forma al curry (por lo que no puede usar la aplicación de función parcial directamente desde C#). Esto se debe a razones de rendimiento: la mayoría de las veces, especifica todos los argumentos y esto se puede implementar de manera más eficiente.
Sin embargo, el principio es que una función toma múltiples parámetros o toma una tupla como parámetro.
Gran respuesta, pero tenga en cuenta que su penúltimo párrafo no es del todo correcto: es perfectamente posible pasar una tupla no sintáctica a un método .NET (por ejemplo, 'let t = 1,2 en Object.ReferenceEquals t') . Sin embargo, esto no funciona para los métodos sobrecargados. – kvb
@kvb: Buen punto: sabía que había algunas limitaciones, pero no estaba exactamente seguro. Gracias por la aclaración. –
¡Impresionante! Respuestas como esta es lo que hace que StackOverflow sea un lugar tan valioso. Gracias Thomas. – Daniel