4

この単純な質問に対する答えが見つかりませんでした。検索に間違ったキーワードを使用した可能性があります。

AST を作成するには、Number、Add、Sub、Mul、Div などのノードが必要です。多くの数学演算は同じ構造を共有しているため、同じパターン マッチングのケースでそれらをすべて扱うにはどうすればよいでしょうか? たとえば、以下の行は構文的に正しくないと言われています。

object AST {
  sealed abstract class Expr
  case class MathOp(e1: Expr, e2: Expr) extends Expr
  case class Number extends Expr

  case class Add(e1: Expr, e2: Expr) extends MathOp(e1, e2)
  case class Sub(e1: Expr, e2: Expr) extends MathOp(e1, e2)
}

意図は、次のことができるようにすることです。

expr match {
  case MathOp(e1: Expr, e2: Expr) => //do something that would be done to Add, Sub, Mul, Div
  case Number => //do another thing
}
4

2 に答える 2

5

case クラスは、パターン マッチング エクストラクタを追加する以上のことを行います。たとえば、equality、product iterator、arity などを追加するため、継承の下で奇妙なことが起こります。そのため、ケース クラスの継承は以前は非推奨であり、現在は Scala 2.10 では不可能です。

あなたの場合、カスタムエクストラクタ(unapplyメソッド)が必要です:

object AST {
  sealed trait Expr
  object MathOp {
    def unapply(m: MathOp): Option[(Expr, Expr)] = Some(m.e1 -> m.e2)
  }
  sealed trait MathOp extends Expr {
    def e1: Expr
    def e2: Expr
  }
  case class Number extends Expr

  case class Add(e1: Expr, e2: Expr) extends MathOp
  case class Sub(e1: Expr, e2: Expr) extends MathOp
}

関連する質問

于 2013-06-19T22:42:20.433 に答える