Twoje założenie jest poprawne, w tym przypadku funkcje są dokładnie takie same.
Można to zobaczyć, sprawdzając wygenerowany kod IL (jak wykazał Craig) i można to również zobaczyć, patrząc na typ wywnioskowany przez kompilator F #. W obu przypadkach zobaczysz int -> int -> int
. Widoki języka F #, które jako funkcja, która pobiera int
i zwraca int -> int
, ale jest faktycznie skompilowana jako metoda z wieloma argumentami (dla wydajności).
Jeśli napiszesz fun
natychmiast po let .. =
, kompilator zamieni to w standardową funkcję. Jednakże, można napisać kod, który jest nieco inny, jeśli nie trochę obliczeń przed zwróceniem funkcję:
let f1 a b = printfn "hi"; a + b
let f2 a = printfn "hi"; (fun b -> a + b)
Teraz te dwie funkcje są bardzo różne, ponieważ drugi jeden drukuje „cześć”, gdy dajesz go tylko pojedynczy argument (i potem wraca do funkcji, które można nazwać):
> let f = f2 1;;
hi // The body is called, prints
val f : (int -> int) // and returns function
> f 2;; // This runs the body of 'fun'
val it : int = 3 // which performs the additiion
można napisać ten sam kod za pomocą f1
, ale pierwsza komenda wystarczy utworzyć nową funkcję, a druga komenda print „hi” i uzupełnij. W takim przypadku wygenerowany kod IL dla f2
będzie różny. Będzie to funkcja, która zwraca funkcję (typu FSharpFunc<int, int>
). Typ wyświetlany przez F # również jest inny - będzie to int -> (int -> int)
zamiast int -> int -> int
. Możesz używać wartości tych dwóch typów dokładnie w taki sam sposób, ale wskazuje na to, że pierwszy z nich może zrobić pewne efekty, gdy podasz mu pojedynczy argument.
Sprawdź [moja odpowiedź tutaj] (http://stackoverflow.com/questions/2175940/int-int-int-what-does-this-mean-in-f/2176428#2176428), może pomóc w zrozumieniu różnica –
Z odpowiedzi uściśliłem pytanie, aby zawierało trzeci przypadek. – hyde