Una normale chiamata di funzione in F # viene scritta senza parentesi e i parametri sono separati da spazi. Il modo più semplice per definire una funzione di diversi parametri è scrivere questo:
let add a b = a + b
Come osservato Pascal, questo modo di parametri che specificano è chiamato currying - l'idea è che una funzione richiede un solo parametro e il risultato è una funzione che accetta il secondo parametro e restituisce il risultato effettivo (o un'altra funzione). Quando si chiama una funzione semplice come questa, si dovrebbe scrivere add 10 5
e il compilatore (in linea di principio) lo interpreta come ((add 10) 5)
. Questo ha alcune belle vantaggi - per esempio, consente di utilizzare applicazione funzione parziale in cui si specifica solo un primo paio di argomenti di una funzione:
let addTen = add 10 // declares function that adds 10 to any argument
addTen 5 // returns 15
addTen 9 // returns 19
Questa funzione è praticamente utile ad esempio quando si elaborano liste:
Ora, passiamo alla parte confusa - in F #, puoi anche lavorare con tuple, che sono tipi di dati semplici che ti permettono di raggruppare più valori in un singolo valore (nota che le tuple non sono legate alle funzioni in ogni modo).È possibile ad esempio scrivere:
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"
Quando si scrive una funzione che accetta parametri tra parentesi separati da una virgola, si sta effettivamente scrivendo una funzione che prende un solo parametro che è 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
Questa è una funzione di un tipo diverso: prende un singolo parametro che è una tupla, mentre la prima versione era una funzione che prendeva due parametri (usando la scrittura).
In F #, la situazione è un po 'più complicata di quella. I metodi .NET appaiono come metodi che accettano una tupla come parametro (quindi puoi chiamarli con la notazione tra parentesi), ma sono un po' limitati (es. non è possibile creare prima una tupla e quindi chiamare il metodo dandogli solo la tupla). Inoltre, il codice F # compilato in realtà non produce metodi nel formato al curry (quindi non è possibile utilizzare l'applicazione di funzione parziale direttamente da C#). Ciò è dovuto a motivi di prestazioni - la maggior parte delle volte, si specificano tutti gli argomenti e questo può essere implementato in modo più efficiente.
Tuttavia, il principio è che una funzione prende più parametri o accetta una tupla come parametro.
Ottima risposta, ma tieni presente che il penultimo paragrafo non è del tutto corretto: è perfettamente possibile passare una tupla non sintattica a un metodo .NET (ad esempio 'let t = 1,2 in Object.ReferenceEquals t') . Questo però non funziona con metodi sovraccaricati. – kvb
@kvb: buon punto - Sapevo che c'erano alcune limitazioni, ma non ero esattamente sicuro. Grazie per il chiarimento. –
Fantastico! Risposte come questa sono ciò che rende StackOverflow un posto così prezioso. Grazie Thomas. – Daniel