2017-05-10 2 views
1

Ich versuche die Scalaz-Struktur zu verstehen und habe einige Schwierigkeiten!Traversing Scalaz Tree

Zuerst habe ich einen Baum definiert:

val tree: Tree[Int] = 
     1.node(
     2.leaf, 
     3.node(
      4.leaf, 
      5.leaf)) 

Bisher mit TreeLoc Ich habe gearbeitet, wie das erste Element zu finden, die etwas Prädikat übereinstimmt. Z.B. den ersten Knoten zu finden, wo der Wert 3:

tree.loc.find(x => x.getLabel == 3) 

Meine war die nächste Herausforderung alle Knoten zu versuchen und zu finden, die etwas Prädikat entsprechen. Zum Beispiel würde ich gerne alle Blattknoten finden (was ziemlich einfach sein sollte mit TreeLoc und isLeaf). Leider kann ich für das Leben von mir nicht herausfinden, wie man den Baum dafür laufen kann.

Edit: Sorry, ich glaube nicht, dass ich in meiner ursprünglichen Frage klar genug war. Um klar zu sein, möchte ich den Baum so gehen, dass ich Informationen über den Knoten habe, die mir zur Verfügung stehen. Flatten, foldRight usw. erlauben mir nur, auf [Int] zu operieren, während ich in der Lage sein möchte, auf Tree [Int] (oder TreeLoc [Int]) zu operieren.

+0

Wie wollen Sie die Ergebnisse? Der einfachste Ansatz (wenn Sie keine spezifischeren Anforderungen haben) wäre, "flatten" in der Struktur zu verwenden und dann den resultierenden "Stream" zu filtern. –

+0

Welche Art von Baumdurchquerung möchten Sie erreichen? Es beeinflusst die Reihenfolge Ihrer Ausgabe (wenn Sie sich wirklich darum kümmern). –

+0

@TravisBrown: meine Anforderung (Entschuldigung, ich hätte dies deutlicher machen sollen) ist, dass ich die Knoten nicht die Werte gehen möchte. In diesem Fall würde flatten mir einen Stream von Einträgen geben, so dass Sie (zum Beispiel) keine Möglichkeit hätten zu wissen, ob der Int von einem Knoten oder einem Blatt kam. – d80tb7

Antwort

1

einen Blick zu haben, wie find in scalaz implementiert ist, ist mein Vorschlag, so etwas wie zu implementieren:

wie die find
implicit class FilterTreeLoc[A](treeLoc: TreeLoc[A]){ 
    def filter(p: TreeLoc[A] => Boolean): Stream[TreeLoc[A]] = 
    Cobind[TreeLoc].cojoin(treeLoc).tree.flatten.filter(p) 
} 

Es verhält sich aber es gibt Ihnen zurück, anstatt eine Stream[TreeLoc[A]] anstelle eines Option[TreeLoc[A]].

Sie können dies als tree.loc.filter(_.isLeaf) und tree.loc.filter(_.getLabel == 3) verwenden.

Hinweis: Die Verwendung einer impliziten Klasse kann offensichtlich vermieden werden, wenn Sie dies lieber als Methode deklarieren lassen möchten.