So vereinfachen Sie verschachtelte Daten, wenn Sie Werte in Haskell zurückgeben

7

Ich möchte den Zustand des vorherigen if condition überprüfen, um zu bestimmen, ob der nächste if condition ausgeführt werden soll oder nicht. Jedes if condition kann einen Wert zurückgeben.

Bearbeiten: Entschuldigung dafür, dass das Beispiel, das ich vorher vorgestellt habe, ein bisschen seltsam aussieht ... :( Dies ist mein reales Beispiel, und ich möchte die if-then-else für goingToMove

vereinfachen %Vor%

Bearbeiten: Schlechtes Beispiel Wenn dieses Ding in Java geschrieben ist, kann ich ein veränderbares boolesches Flag verwenden und veränderbare Daten zurückgeben.

%Vor%

Aber in Haskell, gibt es keine veränderbaren Daten und nur if-then-else condition. Dann sieht der Code so aus, und ich möchte das vereinfachen, weil es in meiner echten Arbeit 8 gibt Ebenen von if-then-else , die schrecklich und unordentlich aussehen ....

%Vor%     
code4j 06.02.2013, 18:20
quelle

5 Antworten

16

In Java, wenn ich folgendes machen wollte:

%Vor%

Was ich im Wesentlichen mache, ist das erste Ergebnis von func1(args) , func2(args) , func3(args) , func4(args) , das nicht null zurückgibt.

In Haskell würde ich func1 , func2 , func3 und func4 als Funktionen modellieren, die einen Maybe a -Wert zurückgegeben haben, so dass sie Nothing zurückgeben könnten, wenn sie fehlgeschlagen sind.

%Vor%

Dann kann ich den Operator <|> verwenden (aus Control.Applicative ), der die folgende Definition für Maybe a hat:

%Vor%

So kann ich das obige Java in

konvertieren %Vor%

Und aufgrund des Wunders der Lazy-Evaluierung wird func2 arg nur ausgewertet, wenn func1 arg Nothing zurückgibt, wie im Java-Beispiel.

    
rampion 06.02.2013, 18:53
quelle
12

Abgesehen von der netten Beschäftigung von <|> , die rampion gab und den ähnlichen Vorschlag von sclv , ist ein anderer üblicher Weg, Wachen zu benutzen und Faulheit auszunutzen,

%Vor%

Aufgrund von Faulheit wird move i ( i = 3, 2, 1 ) nur ausgewertet, wenn es benötigt wird.

In dem gegebenen Fall ist move 3 <|> move 2 <|> move 1 viel schöner, aber in Fällen, in denen die Bedingungen die Auswertung verschiedener Funktionen mit unterschiedlichen Rückgabetypen erfordern, kann die Verwendung von Wächtern und faulen Bindungen in einer where -Klausel die natürliche Lösung sein peinlich geschachtelt if s.

    
Daniel Fischer 06.02.2013 19:20
quelle
1

edit : Hier ist ein Code für das neue Beispiel:

%Vor%

Beachten Sie, dass dies ein Vielleicht zurückgibt. Sie können fromMaybe verwenden, um in einem Standardfall zu bleiben.

Hier ist der alte (aber typecheckende) Code aus dem ersten vorgeschlagenen Beispiel

%Vor%     
sclv 06.02.2013 18:33
quelle
1

Sie möchten routes , wenn seine Länge 2 ist, oder das erste Ergebnis ungleich null aus einer Reihe von Anwendungen von goingToMove , die davon abhängen, welche Eckenfunktion auf p angewendet wird.

%Vor%     
Greg Bacon 07.02.2013 00:07
quelle
0

Eine Option ohne Maybe könnte sein, der Rekursion ein Flag hinzuzufügen (im folgenden Beispiel würden Sie die Funktion mit dem Flag auf 1 setzen):

verschiebe p Routen Punkte w h 1

%Vor%     
גלעד ברקן 07.02.2013 12:31
quelle