在案例类中分解评估

时间:2015-04-19 23:31:42

标签: scala

我从here得到了这个代码:这是一个非常简单的表达式评估

  sealed abstract class Tree
  case class Add(t1: Tree, t2: Tree) extends Tree
  case class Sub(t1: Tree, t2: Tree) extends Tree
  case class Mul(t1: Tree, t2: Tree) extends Tree
  case class Div(t1: Tree, t2: Tree) extends Tree
  case class Num(t: Double) extends Tree

  def eval(t: Tree): Double = t match {
    case Add(t1, t2) => eval(t1)+eval(t2)
    case Sub(t1, t2) => eval(t1)-eval(t2)
    case Mul(t1, t2) => eval(t1)*eval(t2)
    case Div(t1, t2) => eval(t1)/eval(t2)
    case Num(t) => t
  }

如何将eval函数分解为case类(例如Add),这样我就可以得到:( Scala编译器如何为Function *执行此操作,我认为这些应该有相同的答案)

sealed abstract class Tree{
def eval:???
}
case class Add(t1: Tree, t2: Tree) extends Tree{
  def eval = ???
}

1 个答案:

答案 0 :(得分:5)

您可以使抽象Tree类具有返回eval的{​​{1}}方法:

Double

然后:

sealed abstract class Tree {
    def eval: Double
}
case class Add(t1: Tree, t2: Tree) extends Tree {
    def eval = t1.eval + t2.eval
}
case class Sub(t1: Tree, t2: Tree) extends Tree {
    def eval = t1.eval - t2.eval
}
case class Num(t: Double) extends Tree {
    def eval = t
}

另一种方法是为树的每个分支大小定义一个case类:

val tree = Add(Num(1), Sub(Num(2), Num(1))) //1+(2-1)
tree.eval //2.0

然后,您可以相对临时地将新树操作定义为sealed abstract class Tree { def eval: Double } case class Tree2(func: (Double, Double) => Double)(d1: Tree, d2: Tree) extends Tree { def eval = func(d1.eval, d2.eval) } case class Tree1(func: Double => Double)(d1: Tree) extends Tree { def eval = func(d1.eval) } case class Tree0()(d1: Double) extends Tree { def eval = d1 } ,而无需定义新类。这有时是可取的:

vals

当然,val Add = Tree2(_ + _) _ val Sub = Tree2(_ - _) _ val Num = Tree0() _ 这里没什么特别的。您可以使Double通用以参数化返回类型。这是一个小型通用版本,以及Tree的实现:

Strings