[英]Scala how to replace an object in case class tree
我有一个由案例类组成的树,为了简化让我们假设以下内容:
trait Traversable
abstract class Node extends Traversable
case class NodeTypeA(child1:Traversable, text:Leaf) extends Node
case class NodeTypeB(child1:Traversable, child2:Traversable) extends Node
case class SpecialType() extends Node
case class Leaf() extends Traversable
不,我想用我提供给替换函数的其他一些 Traversable 对象替换树中的所有 SpecialType 对象。
我做了一个解决方案,它遍历树并像这样替换 SpecialType 的出现:
def sub(tree: Traversable, substitude: Traversable) : Traversable = {
tree match {
case NodeTypeA(c1, text) => NodeTypeA(sub(c1, substitude), sub(text, substitude))
case NodeTypeB(c1, c2) => NodeTypeB(sub(c1, substitude), sub(c2, substitude))
case SpecialType() => substitude
case other => other
}
}
这有效,但要求我为每个可遍历类型都有一个案例。 有没有办法让它更通用? 在 Scheme 中,我会采用类似的方法,但由于 Scheme 中的所有内容都是列表,因此很容易以通用方式重建所有内容。
所以我希望的是看起来像这样的东西:
t match {
case SpecialType() => s
case s:Traversable => s.type(s.children.all(sub(_, s)))
case other => other
}
这在 Scala 中是否可行?
例子:
sub(NodeTypeA(SpecialType(), Leaf()), NodeTypeB(Leaf(), Leaf()))
output: NodeTypeA(NodeTypeB(Leaf(), Leaf()), Leaf())
您可以让每个班级了解其在替代方案中的作用。
trait Traversable {
def sub(other: Traversable): Traversable = this
}
case class Leaf() extends Traversable
abstract class Node extends Traversable
case class NodeTypeA(child1:Traversable, text:Leaf) extends Node {
override def sub(other:Traversable) = NodeTypeA(child1.sub(other), text)
}
case class NodeTypeB(child1:Traversable, child2:Traversable) extends Node {
override def sub(other:Traversable) = NodeTypeB(child1.sub(other), child2.sub(other))
}
case class SpecialType() extends Node {
override def sub(other:Traversable) = other
}
NodeTypeA(SpecialType(), Leaf()).sub(NodeTypeB(Leaf(), Leaf()))
//res0: NodeTypeA = NodeTypeA(NodeTypeB(Leaf(),Leaf()),Leaf())
这具有返回正确父类型res0: NodeTypeA = ...
的优点,而不是通用res0: Traversable = ...
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.