// Expression trees in Scala, using pattern matching abstract class Expr case class Intexp(var valu:Int) extends Expr case class Plusexp(left:Expr, right:Expr) extends Expr case class Timesexp(left:Expr, right:Expr) extends Expr case class Uminus(sub:Expr) extends Expr object exptrees { /* The following way of defining the eval function may look strange: why not just replace def evalshell with def eval ... ? Because using 'def' to define a function renders it immutable (it's considered a val, not a var). But I want the flexibility of CHANGING the definition of eval later ... when I want to add functionality to eval without redoing it from scratch... */ var eval = (e:Expr) => 0; // dummy def so eval exists (dummy must be of right type) def evalshell(e:Expr):Int = { e match { case Intexp(v) => v case Plusexp(a,Uminus(b)) => eval(a) - eval(b) case Plusexp(a,b) => eval(a) + eval(b) case Timesexp(a,b) => eval(a) * eval(b) case Uminus(a) => -1 * eval(a) }// }//evalshell eval = (e:Expr) => evalshell(e); // change eval to point to evalshell, for now... var str = (e:Expr) => "" // dummy for mutable recursive definition str = (e:Expr) => e match { case Intexp(v) => s"$v" case Uminus(Uminus(a)) => s"${str(a)}" case Uminus(a) => s"-{str(a)}" case Plusexp(a,Uminus(b)) => s"(${str(a)} - ${str(b)})" case Plusexp(a,b) => s"(${str(a)} + ${str(b)})" case Timesexp(a,b) => s"(${str(a)} * ${str(b)})" }//str tostring function def main(argv:Array[String]):Unit = { val tree = Plusexp(Intexp(20),Uminus(Timesexp(Intexp(4),Intexp(2)))) println(str(tree)) println(eval(tree)) }//main }// object exptrees // compile: scalac exptrees.scala, run: scala exptrees