这是一本来自楼梯书的Expr课程。案例树转换
abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
现在,我想要一个函数来重命名表达式中的变量。这是我的第一次尝试。
def renameVar(expr: Expr, varName: String, newName: String): Expr = expr match {
case Var(name) if name == varName => Var(newName)
case Number(_) => expr
case UnOp(operator, arg) => UnOp(operator, renameVar(arg, varName, newName))
case BinOp(operator, left, right) => BinOp(operator, renameVar(left, varName, newName), renameVar(right, varName, newName))
}
val anExpr = BinOp("+", Number(1), Var("x"))
val anExpr2 = renameVar(anExpr, "x", "y")
这很有效,但很繁琐(我正在使用的实际类有几个case子类)。另外,我可能需要几个类似的转换。是否有更好的选择(可能使用更高阶的函数)?
谢谢。这工作。这可以进一步抽象(例如,在一个特质中,这样我就可以在需要时混入这个特性)。实现看起来足够通用,可以通过内省来处理。 – dips 2012-04-26 06:26:42
@dips,有很多方法可以采用这种模式,具体取决于您的需求以及您想要定义所有零件的位置。不知道你想要做什么,很难给出具体的建议,但你可以用它作为进一步探索的起点。 – dhg 2012-04-26 06:29:46