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 に答える