這是一本來自樓梯書的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