【问题标题】:how to implement the visitor pattern for this binary tree?如何实现这个二叉树的访问者模式?
【发布时间】:2020-03-11 17:35:03
【问题描述】:

我有一个二叉树的 ADT:

// ADT for a binary tree
sealed trait BinaryTree[A]
case class Leaf[A](value: A) extends BinaryTree[A]
case class Branch[A](left: BinaryTree[A], right: BinaryTree[A]) extends BinaryTree[A]

如何解决访客模式?

def visit[A](sideEffect: A => Unit, tree: BinaryTree[A]) = ???

【问题讨论】:

  • 请不要破坏您的帖子。

标签: scala


【解决方案1】:

看起来您只想遍历树并将函数应用于所有 Leaf 值。

def visit[A](sideEffect: A=>Unit, tree: BinaryTree[A]):Unit = tree match {
  case Leaf(v)          => sideEffect(v)
  case Branch(lft, rgt) => visit(sideEffect, lft)
                           visit(sideEffect, rgt)
}

【讨论】:

    【解决方案2】:

    在 scala 中,这种操作通常不称为访问者模式。一般来说,功能构造而不是 GOF 模式用于不同的实用任务,例如处理集合等,这要归功于像 catsscalaZ 这样的花哨的库。 Functor 使您能够映射数据结构,还有 Monad 抽象增加了数据结构的创建和 flatMap 操作。 因此,结果类型单元的操作映射将与“访问者”执行相同的操作。

    def map[A,B](tree: BinaryTree[A], f: A => B)
    

    为 ADT 实现 map 的一般方式是用例耗尽的递归:

    def map[A,B](tree: BinaryTree[A], f: A => B): BinaryTree[B]:= 
      match tree {
        case Leaf(a)     => Leaf(f(b))
        case Branch(l,r) => Branch(map(l,f), map(r,f))
      }
    

    您要求的确切“访问者”事情可以通过抛出返回值来完成。 并且您还可以添加一些堆栈安全性,将其调整为尾递归,就像在这个问题中描述的那样:

    How to make tree mapping tail-recursive?

    您还可以为猫类型类创建实例,以使用猫语法并抽象此特定数据结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-05
      • 2012-01-09
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      相关资源
      最近更新 更多