I have such case classes:
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
Now i write such object :
object Main {
type Environment = String => Int
def derive(t: Tree, v: String): Tree = t match {
case Sum(l, r) => Sum(derive(l, v), derive(r, v))
case Var(n) if (v == n) => Const(1)
case _ => Const(0)
}
def eval(t: Tree, env: Environment): Int = t match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
def simple(t: Tree): Const = t match {
case Sum(l, r) if (l.isInstanceOf[Const] && r.isInstanceOf[Const]) => Const(l.asInstanceOf[Const].v + r.asInstanceOf[Const].v)
case Sum(l, r) if (l.isInstanceOf[Sum] && r.isInstanceOf[Sum]) => Const(simple(l).v+ simple(r).v)
case Sum(l, r) if (l.isInstanceOf[Sum]) => Const(simple(l).v + r.asInstanceOf[Const].v)
case Sum(l, r) if (r.isInstanceOf[Sum]) => Const(simple(r).v + l.asInstanceOf[Const].v)
}
def main(args: Array[String]) {
val exp: Tree = Sum(Sum(Var("x"), Var("x")), Sum(Const(7), Var("y")))
val env: Environment = {
case "x" => 5
case "y" => 7
}
println("Expression: " + exp)
println("Evaluation with x=5, y=7: " + eval(exp, env))
println("Derivative relative to x:\n " + derive(exp, "x"))
println("Derivative relative to y:\n " + derive(exp, "y"))
println("Simplified expression:\n" + simple(derive(exp, "x")))
}
}
I am new in scala. Is it possible write method simple with small count of code and maybe in scala way?
Thanks for advice.
You’re almost there. In Scala, extractors can be nested:
Of course, this will give you some warnings about incomplete matches, and the sx @ Sum(_, _) repeatedly suggests that there may be a better approach that includes matching on Const and Var at the root level and making more recursive calls to simple.