Traversieren und Filtern eines Baumes in Haskell

8

Ich bin ziemlich neu in Haskell (arbeite noch an total verständnisvollen Monaden). Ich habe ein Problem, wo ich eine baumartige Struktur habe

%Vor%

Was ich tun möchte, ist in der Lage, dies zu durchqueren und einen neuen Baum mit einem Filter zu erzeugen. Zum Beispiel möchte ich vielleicht alle DataB2 in der Struktur zu "foo" ändern.

Ich habe Beispiele für einen Baum gesehen, wenn sie sich in demselben Datenabschnitt befinden, und die Konstruktoren sind ähnlich.

In der Python-Welt würde ich einfach die Liste durchqueren, mit allem übereinstimmen, was ich brauchte, und den Wert ersetzen.

In Haskell vermute ich, dass ich meinen Baum kopieren kann, aber wie gehen Sie mit Listen um, die in Konstruktoren und Datentypen vergraben sind?

    
Chris 25.02.2010, 23:55
quelle

4 Antworten

9

Sie können dafür generische Programmierung verwenden.

Eine solche generische Programmierbibliothek heißt Scrap Your Boilerplate. Aktivieren Sie oben auf Ihrem Modul die Option Scrap Your Boilerplate, indem Sie Folgendes schreiben:

%Vor%

Importmodul Data.Generics . Dann, neben Show , leite auch Typeable und Data Instanzen für deine Datentypen ab.

Jetzt können Sie die gewünschte Funktion wie folgt schreiben:

%Vor%

Das ist alles, was Sie tun müssen, damit dies funktioniert. Wenn Sie beispielsweise toFoo [DataA1 [], DataA2 "hi", DataA3 "yo" []] aufrufen, lautet die Antwort [DataA1 [],DataA2 "foo",DataA3 "yo" []] .

Hoffe, das hilft!

    
Martijn 26.02.2010, 10:55
quelle
2

Ich kenne keine allgemeine Antwort auf Ihre Frage. Der Datentyp ist ziemlich kompliziert, und ich würde wahrscheinlich eher eine Falte als einen Filter implementieren. Hier sind jedoch einige Filterfunktionen, die Strings in allen vier Positionen aktualisieren können. Ich habe den Code über den Compiler gestellt, also testechecks, aber ich habe es nicht ausgeführt.

%Vor%     
Norman Ramsey 26.02.2010 00:41
quelle
2

Sie möchten die gesamte Datenstruktur durchlaufen und einige Elemente hier und da ändern. Dies geschieht in der Regel durch eine Funktion, die die Datenstruktur als Parameter und übernimmt gibt die neue, geänderte Version der Struktur zurück.

Für jeden Fall von Eingabe definiert diese Funktion, wie der neue Wert, der zurückgegeben wird, sein sollte aussehen wie.

Die Basisfunktion, die ein Tree ändert (was nur eine Liste von DataA Werten ist) Wahrscheinlich sollte nur eine neue Liste von modifizierten Werten zurückgegeben werden. Wenn wir diese aufschieben Änderungen der Werte zu einer modifyA -Funktion, der Hauptänderung Funktion sieht so aus:

%Vor%

Nun muss die Funktion mutateA definiert werden, um alle möglichen DataA -Werte zu ändern, und Am besten wird es von einer mutateB -Funktion begleitet, die DataB -Werte verarbeitet.

Diese Funktionen betrachten die verschiedenen möglichen Fälle von Werten und geben die geeignete neue Werte:

%Vor%

Auf diese Weise wird für jedes Element in der Baumstruktur ein neues Element berechnet, wobei alle DataB2 Werte irgendwo im Baum werden durch "foo" ersetzt.

Es ist relativ ausführlich, weil Sie fünf verschiedene Fälle haben, die eine Liste enthalten von Werten, die durchlaufen werden müssen, aber das ist nicht spezifisch für Haskell. Im eine imperative Sprache, die Sie normalerweise fünf für Schleifen anstelle der fünf haben würden ruft map auf.

Vielleicht könnten Sie Ihre Datenstruktur vereinfachen, um diesen "Overhead" zu reduzieren. Dies hängt natürlich von deinem eigentlichen Anwendungsfall ab, aber vielleicht brauchst du das zum Beispiel nicht die Data2 Fälle: Gibt es einen Unterschied zwischen DataA2 "abc" und DataA3 "abc" [] ?

    
sth 26.02.2010 00:54
quelle
0

Sie können sich die multirec Bibliothek für das Arbeiten mit gegenseitig rekursiven Datentypen ansehen. Ich habe es nicht benutzt, aber nach dem, was du beschrieben hast, klingt es so, als ob es genau auf das Problem gerichtet ist, mit dem du arbeitest. Es verwendet generische Programmierung wie die anderen Antworten, die hier vorgeschlagen wurden, aber möglicherweise sparen Sie die Zeit der Umsetzung alles selbst.

    
C. A. McCann 26.02.2010 15:03
quelle