如何模式匹配案例类的父特征(或类或对象)?

oly*_*lyk 0 scala pattern-matching abstract-syntax-tree case-class

我试图在单个case子句中匹配所有二元运算符,但以下代码给出了错误:

object BinOp is not a case class, nor does it have a valid unapply/unapplySeq member
Note: def unapply(a: AST.this.Expr, b: AST.this.Expr): Option[(AST.this.Expr, AST.this.Expr)] exists in object BinOp, but it cannot be used as an extractor as it has more than one (non-implicit) parameter.
Run Code Online (Sandbox Code Playgroud)

遍历树的核心代码:

tree match {
    case ... other ... cases
    case BinOp(a, b) => traverse(a), traverse(b)
}
Run Code Online (Sandbox Code Playgroud)

AST 类如下:

sealed trait Expr

case class Num(value: java.lang.Number) extends Expr

sealed trait BinOp extends Expr {
  val a, b: Expr
}

object BinOp {
  def unapply(a: Expr, b: Expr): Option[(Expr, Expr)] = Some(a, b)
}

case class Add(a: Expr, b: Expr) extends BinOp

case class Sub(a: Expr, b: Expr) extends BinOp

case class Mul(a: Expr, b: Expr) extends BinOp

case class Div(a: Expr, b: Expr) extends BinOp
Run Code Online (Sandbox Code Playgroud)

为了说明目的,代码段被极大地简化。

Mar*_*lic 5

错误消息似乎提供了信息

def unapply(a: AST.this.Expr, b: AST.this.Expr): Option[(AST.this.Expr, AST.this.Expr)] 
exists in object BinOp, but it cannot be used 
as an extractor as it has more than one (non-implicit) parameter.
Run Code Online (Sandbox Code Playgroud)

所以unapply方法应该用单个参数定义,像这样说

object BinOp {
  def unapply(binOp: BinOp): Option[(Expr, Expr)] = Some(binOp.a, binOp.b)
}
Run Code Online (Sandbox Code Playgroud)