edit: Ich experimentiere normalerweise in ghci, um neuen Code zu verstehen, also für diejenigen wie mich Ich habe eine School of Haskell post/page erstellt, die mit den folgenden Beispielen kommt, aber sie sind editierbar und ausführbar.
Denken Sie, dass diese Beispiele Ihre Fragen beantworten werden, aber aus Zweckmäßigkeit werde ich einen anderen Knoten ändern. Mein Wissen über die Reißverschlussfunktionen in der lens ist eher flach. Es dauert etwas länger zu lesen und sich an die Typen im lens Paket im Vergleich zu vielen anderen Paketen zu gewöhnen, aber danach ist es nicht schlecht. Ich hatte das Reißverschlussmodul oder das Baummodul im Objektivpaket vor diesem Post nicht benutzt.
Die Bäume sind nicht ziemlich gut mit show
Also wenn ich Zeit habe, werde ich zurückkommen und fügen Sie einige schön ausgedruckt setzen, sonst ist es wahrscheinlich der Schlüssel zu arbeiten in der Repl mit diesen Beispielen zu sehen, was passiert.
Anzeigen
Wenn ich den Wert des ersten Knotens anzeigen möchten, nach dem tree lens package dieser wird als Wurzel bezeichnet, dann können Sie:
zipperTree & downward root & view focus
Ändern
zu diesen Wert ändern und den Baum neu (rezip den Baum):
zipperTree & downward root & focus .~ 10 & rezip
Wenn Sie die Zweige nach unten verschieben möchten, müssen Sie downward branches
verwenden. Hier ist ein Beispiel, das die Wurzel des ersten Zweiges modifiziert und rezipx den Baum:
zipperTree & downward branches
& fromWithin traverse
& downward root
& focus .~ 5
& rezip
hier I nach unten in der Liste des branchs bewegen. Ich benutze dann fromWithin
verwenden Sie traverse
, um die Liste zu durchlaufen, wenn dies ein Tupel war, könnte ich stattdessen both
verwenden.
Speichern und Abspielen Traversal Pfade
saveTape
und restoreTape
erlauben Sie Ihre Position in der Reißverschluss zu speichern, so dass es letztere wieder hergestellt werden kann.
Speichern einer Position:
tape = zipperTree & downward branches
& fromWithin traverse
& downward root
& saveTape
dann die Traversal durch den Baum neu erstellen Ich kann:
t <- (restoreTape tape testTree)
Dann können Sie t als neuer Reißverschluss verwenden und es als normal ändern:
t & focus .~ 15 & rezip
Das Band wiederholt die Schritte, die Sie genommen haben, also kann auf anderen Bäumen arbeiten, also würde das Folgen mit t arbeiten er Band, wie oben definiert:
testTree2 = Node 1 [ Node 2 [] ]
t2 <- (restoreTape tape testTree2)
t2 & focus .~ 25 & rezip
Ändern Mehrere Standorte
Wenn Sie mehrere Wurzeln halten Sie einfach auf reziping den Reißverschluss ändern möchten. Die folgende modifiziert die beiden Wurzeln der testTree2:
zipper testTree2 & downward root
& focus .~ 11
& upward
& downward branches
& fromWithin traverse
& downward root
& focus .~ 111
& rezip
Danke dafür. Allerdings spricht es meine Hausaufgaben nicht ganz an (nur Spaß). Ich versuche nicht, einen bestimmten Knoten zu modifizieren. Stattdessen möchte ich den gesamten Baum durchlaufen und den Pfad zu einem bestimmten Knoten aufzeichnen, der eine Bedingung erfüllt. In Ihrem "Modifizierungs" -Beispiel wissen Sie, dass der Pfad "reißverschlussbaum & innen (root.traverse.branches) >> = saveTape" ist. Ich habe mich gefragt, wie ich den Weg finden kann, ohne ihn vorher zu kennen (indem ich ihn überquere). – Kai
Ein konkretes Beispiel mit mehr Details wäre dann hilfreich. Mit den obigen Primitiven und der Rekursion ist es möglich, jeden Knoten in der Baumstruktur zu betrachten, jeden Wert zu betrachten und einen Test darauf anzuwenden. Nachdem der Test erfolgreich war, würden Sie einfach das Band zurückgeben oder es in einem Zustand oder Schreiber monad speichern, wenn das für Ihre Anwendung besser ist. – Davorak
Das ist sehr hilfreich! Wie verwende ich Data.Tree.Lens für meine eigenen Baumtypen? Was ist, wenn es sich um einen binären Baum anstelle eines Rosenbaums handelt? – nont