2016-07-16 15 views
3

Wann sollte ich "ignore" anstelle von "()" verwenden?So refaktorieren Sie eine Funktion mit "ignorieren"

ich versuchte, die folgend zu schreiben:

let log = fun data medium ->() 

erhielt ich dann die folgende Meldung:

Lint: 'Spaß _ ->()' könnte in der Lage sein, in Refactoring wird ' ignorieren'.

So aktualisiert ich die Erklärung auf die folgenden:

let log = fun data medium -> ignore 

Gibt es eine Anleitung, warum ich einen über den anderen verwenden könnte?

Mein Bauch sagt mir, dass ich ignorieren sollte, wenn Sie einen tatsächlichen Ausdruck ausführen. In diesem Fall erkläre ich jedoch eine höherwertige Funktion.

Sind meine Annahmen richtig?

+2

'let log = Spaß Datenträger ->()' gibt Einheit zurück, während 'log = Spaß Datenträger -> Ignorieren' gibt eine Funktion zurück, die Einheit zurückgibt - die eine ersetzt nicht die andere. Die Flusen-Nachricht zeigt an, dass die erste, anders als binär statt unär, semantisch dasselbe wie "ignorieren" ist. – ildjarn

+0

Wie oft erwähnt, sollten Sie, wenn Sie 'ignore' verwenden oder eine Kompiliernachricht verwenden, um' ignore' zu ​​verwenden, den Code wirklich betrachten und verstehen, warum dies normalerweise ein Designproblem ist und nicht wie. Wie ich oft bemerke, brauche ich selten "ignorieren" und es ist fast immer mit Benutzer-I/O, z. [Console.ReadKey() |> Ignorieren] (http://StackOverflow.com/a/24215845/1243762) oder Interagieren mit nicht-funktionalem Code wie .NET-Methoden, z.B. [Ein Berechnungsausdruck-Wrapper für StringBuilder] (http://www.fssnip.net/d5) –

+0

In meinem Fall soll meine Log-Funktion über I/O mit der Außenwelt interagieren. –

Antwort

2

Nie, zumindest nicht in der Art und Weise in der Frage gezeigt.

zwischen ignore und () Substitution ist nicht sinnvoll, da sie unterschiedliche Konzepte sind:

  • ignore ist eine generische Funktion mit einem Argument und Einheit zurückzukehren. Sein Typ ist 'T -> unit.
  • () ist der einzige gültige Wert vom Typ unit. Es ist überhaupt keine Funktion.

Daher ist es nicht gültig, den Refektor in der Frage zu tun. Die erste Version von log dauert zwei Curry-Argumente, während die zweite Version drei dauert.

Was Lint vorschlägt, ist nicht ganz klar. ignore ist eine Funktion mit einem Argument; Es ist nicht offensichtlich, wie (oder warum) es verwendet werden sollte, um eine Methode umzuformen, die zwei Curry-Argumente benötigt. fun _ _ ->() wäre eine gute und gut lesbare Möglichkeit, zwei Argumente zu ignorieren.

5

Die Linter-Nachricht, die Sie hier erhalten haben, ist ein bisschen verwirrend. Die ignore Funktion ist nur eine Funktion, die alles und kehrt Einheit nimmt:

let ignore = fun x ->() 

Ihre log Funktion ist ein bisschen ähnlich wie ignore, aber es hat zwei Parameter:

let log = fun data medium ->() 

In F #, das ist eigentlich eine Funktion, die eine andere Funktion zurückgibt (currying).Sie können sagen, dies explizit schreiben:

let log = fun data -> fun medium ->() 

Jetzt können Sie sehen, dass ein Teil Ihrer Funktion eigentlich das gleiche wie ignore ist. Sie können schreiben:

let log = fun data -> ignore 

Dies bedeutet das gleiche wie Ihre ursprüngliche Funktion und das ist, was der Linter vorschlägt. Ich würde den Code nicht auf diese Weise schreiben, weil es weniger offensichtlich ist, was der Code tut (er benötigt tatsächlich zwei Argumente) - Ich denke, der Linter sucht nur nach dem einfachen Muster, ignoriert die Tatsache, dass manchmal das Refactoring nicht alles ist sinnvoll.

Verwandte Themen