abstract class Expr { def isNumber: Boolean def isSum: Boolean def numValue: Int def leftOp: Expr def rightOp: Expr } class Number(n: Int) extends Expr { def isNumber: Boolean = true def isSum: Boolean = false def numValue: Int = n def leftOp: Expr = error("Number.leftOp") def rightOp: Expr = error("Number.rightOp") } class Sum(e1: Expr, e2: Expr) extends Expr { def isNumber: Boolean = false def isSum: Boolean = true def numValue: Int = error("Sum.numValue") def leftOp: Expr = e1 def rightOp: Expr = e2 } def eval(e: Expr): Int = { if (e.isNumber) e.numValue else if (e.isSum) eval(e.leftOp) + eval(e.rightOp) else error("unrecognized expression kind") } // try eval( new Sum(new Number(1), new Sum(new Number(3), new Number(7))) ) def printExpr(e: Expr) { if (e.isNumber) print(e.numValue) else if (e.isSum) { print("(") printExpr(e.leftOp) print("+") printExpr(e.rightOp) print(")") } else error("unrecognized expression kind") }