(fun a -> ...)
to po prostu funkcja anonimowa. F # różni się od C# tym, że funkcje są pierwszorzędnymi obywatelami, więc po powiązaniu anonimowej funkcji z f
, da to f
podpis typu val f : int -> int
(ponieważ a
jest wywnioskowany jako int32
), tak jakbyś związał normalny, nazwany działaj jak w drugim przykładzie. Możesz udowodnić, że są semantycznie identyczne, uruchamiając swoje przykłady w języku F # interaktywnym.
Edit: Funkcje anonimowych nawet wspierać rodzajowych, które są zwykle wywnioskować, ale można je wyraźnie, jak to:
let f<'T> = (fun (x: 'T) -> x)
Edycja 2: od F # 3.1 specyfikacji projektu (found here):
Definicja wartości jest uważana za definicję funkcji, jeśli jej bezpośrednia prawa strona jest anonimową funkcją, jak w tym przykładzie: let f = (fun w -> x + w)
Odkładając oczywisty błąd składni na bok, chodzi o to, że wiąże się wartość funkcji (tj. funkcja anonimowa) do identyfikatora jest dosłownie odpowiednikiem normalnej definicji funkcji. Mówi się, że ta równoważność jest "podstawą programowania funkcjonalnego", więc możesz być pewny, że to się nie zmieni w przyszłości.
Dla celów ogólnych, F # traktuje funkcjonować definicje i wartości funkcji (tj instancji delegata funkcje anonimowe) jako równe w czasie projektowania, ale kiedy trzeba podnieść definicję funkcji do wartości funkcji, użyje delegat typu FSharpFunc jako typ kompilowany. Dzieje się tak w przypadku wszystkich funkcji wyższego rzędu, takich jak te w modułach Array, List, Seq i tak dalej, ponieważ nie ma rzeczywistego sposobu użycia metody CIL jako wartości funkcji, podobnie jak w przypadku delegatów. Wszystko inne wygląda dokładnie tak, jakbyś oczekiwał skompilowanego C# lub VB.NET do - to tylko delegaci, dla których F # używa FSharpFunc.
Edycja 3: Nie mogę jeszcze dodawać komentarzy, ale jeśli chodzi o odpowiedź Tomasa, kompilator F # nie wie, jak uogólnić wyrażenie let h =(); fun a -> a
, ale zaakceptuje je, jeśli sam doda adnotacje typu , podobnie jak w przykładzie Nikona id
.
Edytuj 4: Oto niesamowicie surowy obraz kompilacji funkcji F #. Zauważ, że przykład Tomasa, wyrażenie sekwencyjne, jak go nazwał, zmienia się w FSharpFunc, podczas gdy równoważna funkcja bez ();
staje się rzeczywistą metodą CIL. Właśnie o tym mówiła specyfikacja F #. Ponadto, gdy używasz zwykłej metody CIL jako wartości, przy częściowym zastosowaniu lub w inny sposób, kompilator stworzy FSharpFunc, który będzie go reprezentował jako zamknięcie. 
Dziękuję, to jest wyjątkowo wszechstronne! Dokładnie tekst z gwarancją, której szukałem. Nie znam kultury społeczności związanej z tą akcją, ale uważam, że twoja odpowiedź jest teraz lepsza niż odpowiedź @ TomasPetricek, więc zaakceptowałem ją. – Rhyme