模式匹配编译器的通用案例类

时间:2013-11-13 12:36:22

标签: scala compiler-construction pattern-matching

我用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型。

现在我的想法是,这种情况永远不会发生。什么是优雅的解决方案?最好使用案例类和泛型类型。

1 个答案:

答案 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
}