我有以下案例类。表达式是盒装数学运算和数字。例如,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可能也是嵌套的添加。
答案 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
类型,例如,预期结果类型的评估。