我用Scala创建了一个相当简单的抽象语言。到目前为止,我试图通过使用scalas通用案例类来实现类型错误,但已达到理解的心理障碍。 - 这是我目前的(不工作)解决方案:
sealed abstract class TypedExpr[T]
case class CstI(value: Int) extends TypedExpr[Int]
case class Add(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Int]
case class Times(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Int]
case class LessThanEq(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Boolean]
case class IfThenElse[T](cond: TypedExpr[Boolean], e1: TypedExpr[T], e2: TypedExpr[T]) extends TypedExpr[T]
object Language {
def eval[T](e: TypedExpr[T]): T = e match {
case CstI(n) => n
case Add(e1, e2) => eval(e1) + eval(e2)
case Times(e1, e2) => eval(e1) * eval(e2)
case LessThanEq(e1, e2) => eval(e1) <= eval(e2)
case IfThenElse(cond, e1, e2) => if (eval(cond)) eval(e1) else eval(e2)
}
}
截至目前,我因fx而遇到类型错误。 CstI不属于T型。
现在我的想法是,这种情况永远不会发生。什么是优雅的解决方案?最好使用案例类和泛型类型。
答案 0 :(得分:1)
由于我使用IntelliJ,我也因为错误而感到沮丧。我重写了你的解决方案,不确定它是否适用于你的情况,但我想我会发布它 - 也许它会有所帮助。我将评估函数移到了TypedExpr
:
sealed trait TypedExpr[T] {
def eval: T
}
case class CstI(value: Int) extends TypedExpr[Int] {
def eval = value
}
case class Add(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Int] {
def eval = e1.eval + e2.eval
}
case class Times(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Int] {
def eval = e1.eval * e2.eval
}
case class LessThanEq(e1: TypedExpr[Int], e2: TypedExpr[Int]) extends TypedExpr[Boolean] {
def eval = e1.eval <= e2.eval
}
case class IfThenElse[T](cond: TypedExpr[Boolean], e1: TypedExpr[T], e2: TypedExpr[T]) extends TypedExpr[T] {
def eval = if (cond.eval) e1.eval else e2.eval
}
object Language {
def eval[T](e: TypedExpr[T]): T = e.eval
}