Wie schreibe ich diesen Dreiliner als One-Liner?

7

Ich mag den Weg, Sie können One-Liner-Methoden in Scala, z. mit List(1, 2, 3).foreach(..).map(..) .

Aber es gibt eine bestimmte Situation, die manchmal beim Schreiben von Scala-Code auftaucht, wo die Dinge ein bisschen hässlich werden. Beispiel:

%Vor%

In dieser Situation müssen wir ein Ergebnis zurückgeben, aber wir können es nicht direkt zurückgeben, nachdem die Berechnung durchgeführt wurde, da wir vor der Rückkehr etwas aufräumen müssen.

Ich muss immer einen Dreiliner schreiben. Gibt es auch die Möglichkeit, einen Einzeiler zu schreiben, um dies zu tun (ohne die Klasse von A zu ändern, weil dies eine externe Bibliothek sein kann, die nicht geändert werden kann)?

    
John Threepwood 09.07.2012, 08:53
quelle

5 Antworten

9

Hier sind ganz klar die Nebenwirkungen beteiligt (ansonsten wäre die Reihenfolge des Aufrufs von calculateImportantThings und cleanUp egal), also wäre es gut, wenn Sie Ihr Design überdenken.

Wenn das jedoch keine Option ist, könnten Sie etwas wie

ausprobieren %Vor%

Der Tupelwert (a, b) entspricht der Anwendung Tuple2(a, b) und die Scala-Spezifikation garantiert, dass ihre Argumente von links nach rechts ausgewertet werden, was Sie hier wollen.

    
Miles Sabin 09.07.2012 09:21
quelle
7

Dies ist ein perfekter Anwendungsfall für try / finally :

%Vor%

Dies funktioniert, weil try / catch / finally ein Ausdruck in scala ist, was bedeutet, dass er einen Wert zurückgibt, und noch besser, Sie erhalten die Bereinigung, ob die Berechnung eine Ausnahme auslöst.

Beispiel:

%Vor%     
Luigi Plinge 09.07.2012 15:26
quelle
5

Es gibt tatsächlich einen Haskell-Operator für genau diese Gelegenheit:

%Vor%

Zum Beispiel:

%Vor%

Dann bleibt nur noch derselbe Operator in scalaz , da scalaz normalerweise alles repliziert, was Haskell hat . Sie können Werte in Identity umbrechen, da Scala nicht über IO verfügt, um Effekte zu klassifizieren. Das Ergebnis würde etwa so aussehen:

%Vor%

Dies ist jedoch ziemlich störend, da wir die seitenwirksamen Berechnungen explizit in "Identität" einschließen müssen. Nun, die Wahrheit ist, Scalaz macht eine Magie, die implizit in und aus dem Identity-Container konvertiert, so dass Sie einfach schreiben können:

%Vor%

Sie tun müssen dem Compiler irgendwie mitteilen , dass sich die linke Seite in der Identitätsmonade befindet. Das obige war der kürzeste Weg, an den ich denken konnte. Eine andere Möglichkeit ist die Verwendung von Identity() *> foo <* bar , die die Effekte von foo und bar in dieser Reihenfolge aufruft und dann den Wert von foo erzeugt.

Um zum ghci-Beispiel zurückzukehren:

%Vor%     
Dan Burton 09.07.2012 11:54
quelle
5

Vielleicht möchten Sie einen Turmfalken-Kombinator verwenden? Es ist wie folgt definiert:

  

Kxy = x

Sie rufen es also mit dem Wert auf, den Sie zurückgeben möchten, und einigen Nebeneffekten, die Sie ausführen möchten.

Sie können es wie folgt implementieren:

%Vor%

... und benutze es auf diese Weise:

%Vor%

Weitere Informationen finden Sie hier: deasish gosh blog .

[UPDATE] Wie Yaroslav richtig bemerkt, ist dies nicht die beste Anwendung des Turmfalken-Kombinators. Aber es sollte kein Problem sein, einen ähnlichen Kombinator zu definieren, der eine Funktion ohne Argumente verwendet, stattdessen:

%Vor%

könnte jemand verwenden:

%Vor%     
Christian 09.07.2012 09:16
quelle
2
%Vor%

Sie können sich das Projekt scala-arm für eine typenklassenbasierte Lösung ansehen.

    
xiefei 09.07.2012 09:19
quelle

Tags und Links