1

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

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

4

1 回答 1

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
}
于 2013-11-13T13:31:16.110 回答