Was ist der Unterschied zwischen diesen Funktionen?

8

Sind diese Funktionen genau gleich? Das heißt, sind die 1. und 2. Syntax nur bequeme Abkürzungen für die letzte Syntax? Oder gibt es einen theoretischen oder praktischen Unterschied, und wenn ja, was ist das?

let f1 a b = a + b

let f2 a = (fun b -> a + b)

let f3 = (fun a -> (fun b -> a + b) )

Sie scheinen mir gleich zu sein, f1 5 , f2 5 und f3 5 scheinen zum Beispiel den gleichen Wert zurückzugeben. Ich überprüfe nur, dass ich hier keine ungültige Annahme mache. Mit anderen Worten, ich hoffe eine wissensbasierte Antwort, nicht eine, die sagt "Ja, ich glaube, sie sind die gleichen".

    
hyde 30.10.2012, 12:55
quelle

3 Antworten

8

Ihre Annahme ist richtig, in diesem Fall sind die Funktionen genau gleich.

Sie können das sehen, indem Sie den generierten IL-Code untersuchen (wie von Craig gezeigt) und Sie können dies auch sehen, indem Sie den vom F # -Compiler abgeleiteten Typ betrachten. In beiden Fällen sehen Sie int -> int -> int . Die F # -Sprache sieht dies als eine Funktion an, die int übernimmt und int -> int zurückgibt, aber sie wird tatsächlich als eine Methode mit mehreren Argumenten kompiliert (für Effizienz).

Wenn Sie fun unmittelbar nach let .. = schreiben, verwandelt der Compiler das in eine Standardfunktion. Sie können jedoch Code schreiben, der ein wenig anders ist, wenn Sie vor dem Zurückgeben der Funktion eine Berechnung durchführen:

%Vor%

Nun sind die beiden Funktionen sehr unterschiedlich, weil die zweite Funktion "hi" ausgibt, wenn Sie nur ein Argument angeben (und dann eine Funktion zurückgibt, die Sie aufrufen können):

%Vor%

Sie können denselben Code mit f1 schreiben, aber der erste Befehl erstellt nur eine neue Funktion und der zweite Befehl wird "hi" ausgeben und die Addition durchführen.

In diesem Fall wird der generierte IL-Code für f2 unterschiedlich sein. Es wird eine Funktion sein, die eine Funktion (vom Typ FSharpFunc<int, int> ) zurückgibt. Der Typ, der von F # angezeigt wird, ist auch anders - es wird int -> (int -> int) statt int -> int -> int sein. Sie können die Werte dieser beiden Typen auf die gleiche Weise verwenden, aber es weist darauf hin, dass die erste möglicherweise einige Auswirkungen hat, wenn Sie ein einzelnes Argument angeben.

    
Tomas Petricek 30.10.2012, 13:05
quelle
5

Hier ist die IL für f1 :

%Vor%

... und für f2:

%Vor%

Wie Sie sehen können, ist es im Wesentlichen identisch, also ja, sie sind die gleichen.

    
Craig Stuntz 30.10.2012 13:05
quelle
5

Zwei Funktionen sind gleich. Sie könnten als syntaktische Zucker für

betrachtet werden %Vor%

Es gibt einen kleinen praktischen Unterschied. f1 betont, dass die Funktion einen Wert zurückgibt, während f2 eine Schließung zurückgibt, die wiederum einen Wert erzeugt. Die Verwendung von f2 ist ein wenig attraktiver beim Erstellen von Kombinatoren, z. Parser-Kombinatoren .

Nebenbei bemerkt, es gibt keine Gleichheit bei Funktionen in F #, also sind f1 5 und f2 5 unterschiedliche Werte, aber sie erzeugen die gleichen Ausgaben an den gleichen Eingängen.

    
pad 30.10.2012 13:09
quelle

Tags und Links