2017-05-10 9 views
1

スカラズの木構造を理解しようとしていて、何か難しかったです!Scalaz Treeをトラバースする

まず私は、ツリーを定義した:

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

は、これまでのところ、私はいくつかの述語と一致する最初要素を検索する方法を働いてきたTreeLocを使用。例えば。値が3で最初のノードを見つけるために:

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

を私の次の課題は、いくつかの述語に一致するすべてノードを試してみて、見つけることでした。たとえば、私はすべての葉ノードを見つけたいと思っています(TreeLocisLeaf)。残念ながら、私の人生は、これを行うために木を歩く方法を解決することはできません。

編集:申し訳ありません申し訳ありませんが私は私の元の質問で十分に明確だったとは思わない。明確にするために、私はノードが私に利用可能であるという情報があるような方法でツリーを歩きたい。 Flatten、foldRightなどはTree [Int](またはTreeLoc [Int])で操作できるようにしたいのですが、[Int]で操作できるようにしてください。

+0

どのように結果を望みますか?最も簡単なアプローチ(より具体的な要件がない場合)は、ツリー上で 'flatten'を使用して、結果の' Stream'をフィルタリングすることです。 –

+0

達成したいツリートラバーサルのタイプは何ですか?出力の順序に影響します(実際に気にしている場合)。 –

+0

@TravisBrown:私の要件(申し訳ありませんが、私はこれについてもっと明確にすべきでした)は、ノードではなく値を歩きたいということです。この場合、Flattenは私にStream of Intsを与えます。そのため、intがNodeまたはLeafから来たものかどうかを知る方法がありません。 – d80tb7

答えて

1

findがscalazに実装される方法に表情を持つが、私の提案のようなものを実装することです:それは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) 
} 

をそれはOption[TreeLoc[A]]するのではなく、代わりにバックStream[TreeLoc[A]]をあなたを与えます。

tree.loc.filter(_.isLeaf)tree.loc.filter(_.getLabel == 3)として使用できます。

注:代わりにメソッドとして宣言したい場合は、暗黙的なクラスの使用を避けることはできます。