遍历 Scalaz 树

Traversing Scalaz Tree

我正在尝试理解 scalaz 树结构,但遇到了一些困难!

首先我定义了一棵树:

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

到目前为止,使用 TreeLoc 我已经弄清楚了如何找到与某些谓词匹配的 first 元素。例如。找到值为 3 的第一个节点:

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

我的下一个挑战是尝试找到 所有 匹配某些谓词的节点。例如,我想找到所有叶节点(使用 TreeLocisLeaf 应该很容易)。不幸的是,我一生都无法弄清楚如何走树来做到这一点。

编辑: 抱歉,我认为我在最初的问题中不够清楚。明确地说,我想以这样一种方式遍历树,即我可以获得有关节点的信息。 Flatten、foldRight 等只允许我对 [Int] 进行操作,而我希望能够对 Tree[Int](或 TreeLoc[Int])进行操作。

看看 find 在 scalaz 中是如何实现的,我的建议是实现类似的东西:

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

它的行为类似于 find,但它返回的是 Stream[TreeLoc[A]] 而不是 Option[TreeLoc[A]]

您可以将其用作 tree.loc.filter(_.isLeaf)tree.loc.filter(_.getLabel == 3)

注意:如果您希望将此声明为方法,则显然可以避免使用隐式 class。