在scala中添加案例类的字段

时间:2016-05-11 19:45:05

标签: java scala types pattern-matching field

我有以下案例类。表达式是盒装数学运算和数字。例如,add是表达式的子类,它递归地包含两个字段num,它们也是表达式的子类。

  abstract class Expression
  case class num (num: Int) extends Expression
  case class add  (left: Expression, right: Expression) extends Expression

  abstract class Result
  case class numericResult (v : Int) extends Result

还有其他类型的Return,因此我无法移除案例类

评估方法应该采用表达式,然后取消框,然后执行操作并返回Result类中的框结果

def evaluate(expr: Expression ) : Result = {
    expr match {
      case num(n) => new numericResult(n)
      case add(l, r) => new numericResult(evaluate(l).v + evaluate(r).v) //add will never be called on imaginary numbers
      case addi(l, r) => new imaginaryResult(...)  //adds imaginary numbers

    }
}

但是当我尝试评估它时,我收到一个错误:

error: value v is not a member of Result

如何确保Scala知道l和r的类型为num,并且在评估时会给出numericResult而不是Result?我可以假设,如果add evaluate(l)和evaluate(r)将返回numericResut,但l和r可能也是嵌套的添加。

2 个答案:

答案 0 :(得分:1)

根据Expression生成的Result类型对abstract class Expression[T <: Result] case class num (num: Int) extends Expression[numericResult] case class add (left: Expression[numericResult], right: Expression[numericResult]) extends Expression[numericResult] case class addi (left: Expression[Result], right: Expression[Result]) extends Expression[imaginaryResult] abstract class Result // why lower-case? case class numericResult (v : Int) extends Result case class imaginaryResult(v: Int) extends Result def evaluate [T <: Result](expr: Expression[T] ) : T = { expr match { case num(n) => new numericResult(n) case add(l, r) => new numericResult(evaluate(l).v + evaluate(r).v) //add will never be called on imaginary numbers case addi(l, r) => new imaginaryResult(???) //adds imaginary numbers } } 进行参数化:

.prepend()

答案 1 :(得分:0)

以下是在运行时验证评估结果的变体:

def evaluate(expr: Expression ) : Result = {
    expr match {
      case num(n) => new numericResult(n)
      case add(l, r) => (evaluate(l), evaluate(r)) match {
           case (numericResult(l), numericResult(r)) => new numericResult(l + r)
           case (x, y) => throw new IllegalStateException(s"Numeric Results expected, got $x, $y")
      }
      case addi(l, r) => new imaginaryResult(...)  //adds imaginary numbers
    }
}

但是,为了在编译时获得类型安全性,您需要考虑使用dependent types来补充Expression类型,例如,预期结果类型的评估。