Frage

Zur Zeit eine Reihe von Blogeinträgen auf F # lesen, an den C # Programmierern gezielt. Im Moment habe ich fertig Leseteil 3 ( http://www.jelovic.com/weblog/ ? p = 220 ) und sind links verwirrt.

Der Unterschied zwischen

lassen readline = Console.ReadLine ()

und

lassen readline () = Console.ReadLine ()

ist klar genug, aber warum gibt es die Notwendigkeit, die beiden Klammern angeben - () - in der folgenden Zeile:

lassen print (Text: string) () = Console.WriteLine Text

sollte nicht die Compiler Abbildung der Lage sein, aus Sie einen Delegaten Druck sind erklärt durch die Klammern weggelassen, so dass es aussehen würde wie folgt:

lassen print (Text: string) = Console.WriteLine Text

Auch die folgende Zeile machte wenig Sinn für mich

In der Regel, wenn Sie eine Funktion, die Parameter eines anderen Typs nimmt der Compiler zwischen einem Funktionsaufruf und einem Delegierten Referenz, aber für Einheit unterscheiden können Sie es erzwingen müssen.

Bedeutet dies, dass, wenn die Parameter unterschiedlich sind, es ist sicher für den Compiler, es ist ein Funktionsaufruf zu übernehmen?

danke Ihnen allen für die Antworten, es ist klar, jetzt zu mir. Wie für das Angebot, teilen wir es ruhen.

War es hilfreich?

Lösung

Einleitung. Ich denke, es ist sinnvoll, zunächst den Unterschied in dem einfachen Beispiel zu diskutieren, da es hilft zu verstehen, was „Einheit“ Wert ist. Die erste Deklaration erzeugt einen String-Wert (und ruft sofort ReadLine die Eingabe vom Benutzer zu erhalten):

> let readLine = Console.ReadLine ();;
val readLine : string

Die zweite Erklärung erzeugt eine Funktion, den Einheitswert als Argument annimmt. Die Funktion benötigt keine Eingabe zu nehmen, aber wir wollen es als eine Funktion definieren, so dass es immer wieder ausgeführt werden können (wir benötigen, weil die Funktion Nebeneffekt - es liest Eingabe von dem Benutzer).

Die „Einheit“ Parameter sind nur ein Weg, um eine Funktion zu erstellen, die etwas als Argument. „Einheit“ hat nur einen einzigen Wert als () geschrieben, so dass es keine Informationen darstellen - nur die Tatsache, dass es einige Parameter ist:

> let readLine () = Console.ReadLine ();;
val readLine : unit -> string

Ihre Frage. mit zusätzlichen Streben bei Ihrem Beispiel suchen. Dies erzeugt eine Funktion, die eine Zeichenfolge als erste Parameter nimmt und nimmt zusätzlichen „Einheit“ Wert als zweiten Parameter. Sie können, dass aus der Art Unterschrift sehen:

> let print (text : string) () = Console.WriteLine text 
val print : string -> unit -> unit

Dies gilt F # Erklärung, aber es ist nicht sehr nützlich. Es bedeutet, dass die Funktion nur aufgerufen werden, wenn Sie ihm eine Schnur geben zu drucken und auch zusätzlichen „Einheit“ Wert. Sie können es so nennen:

print "Hello" ()

Auch ohne die zusätzlichen „Einheit“ Parameter, wäre es eine Funktion sein (wie auf einen Wert entgegengesetzt), so dass das Hinzufügen der zusätzlichen Parameter nicht hilft (Sie erstellen immer eine Funktion, die aufgerufen werden kann, verschiedene Zeichenkette drucken ).

Es gibt immer noch Fälle, in denen sich diese Erklärung interessant sein kann. Zum Beispiel können Sie die Funktion nur mit der Zeichenfolge als Parameter aufrufen. In diesem Fall werden Sie eine Funktion wie das Ergebnis. Die zurückgegebene Funktion Einheit nehmen und wird die Zeichenfolge drucken:

let f = print "Hello" // doesn't print anything
f ()                  // prints "Hello"
f ()                  // prints "Hello" again!

Also, der Compiler ermöglicht es Ihnen, „Einheit“ Werte wie alle anderen Werte in der Sprache zu verwenden. Dazu gehören Anwendungen, die auf den ein wenig fremd (und nicht sehr nützlich) zuerst aussehen kann, aber ein gutes Gefühl in irgendeinem Szenario machen.

Andere Tipps

Dieses:

let print (text : string) = Console.WriteLine text

schafft eine Methode, wie zu drucken:

print "hi" // prints "hi" in the console

Dabei gilt:

let print (text : string) () = Console.WriteLine text

erzeugt eine Methode eine bestimmte Zeichenfolge drucken wie:

let printHi = print "hi" // Does NOT print a string to the console

printHi () // But now this does print "hi" :)
printHi () // And this...

So im Wesentlichen, es ist eine „Druck bestimmt Zeichenfolge X Konsolenfunktion“ Fabrik, die das Ergebnis (ex printHi) kann viele Male wiederverwendet werden.

Mit currying,

let makePrinter (text : string) () = Console.WriteLine text

Lassen Sie uns Sie eine Funktion erstellen, dass immer druckt eine bestimmte Zeichenfolge, zum Beispiel

let helloPrinter = makePrinter "hello"

gibt "Hallo" einfach durch Aufruf

helloPrinter ()

Auf der anderen Seite,

let print (text : string) = Console.WriteLine text

gibt sofort "Text", wenn genannt

print "hello"

und kehrt (), nicht eine Funktion vom Typ unit -> unit wie in dem ersten, curried Fall.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top