2014-09-21 13 views
1

请考虑以下在实数表达式上实现二元运算的实例&。如何匹配多个case类并提取相同的(-named)参数?

abstract class DoubleE 
case class Negate(x: DoubleE) extends DoubleE 
case class Reciprocal(x: DoubleE) extends DoubleE 
case class Mult(lhs: DoubleE, rhs: DoubleE) extends DoubleE 
case class Div(lhs: DoubleE, rhs: DoubleE) extends DoubleE 
... 
// a lot more binary operations 

现在,我想要做的事,如:

(e: DoubleE) match { 
    case DoubleEUnary(x) => ... // use x ... 
    case DoubleEBinary(a, b) => ... // use a and b ... 
} 

,有时我甚至想指匹配系为好;例如

e match { 
    case DoubeEBinary(a, b) => DoubleEBinary(b, a) 
    ... 
} 

一些失败的尝试,我已经试过的:

  • abstract case class DoubleEBinary(a: DoubleE, b: DoubleE) +从延伸,但这是不允许的:错误:...外壳到外壳继承被禁止。为了克服这种限制,使用提取到图案匹配由误差上面所暗示的非叶节点
  • abstract case class DoubleEBinary(a: DoubleE, b: DoubleE) 
        def unapply(binOp: DoubleEBinary) = Some((a, b)) 
    

    不工作或者:错误:未找到:值DoubleEBinary

  • 尝试使用情况下别名
    • case binOp @ (Mult(a, b) | Div(a, b) | ...) => ...
    • case binOp(a, b) @ (Mult(_, _) | Div(_, _) | ...) => ...
    • case (binOp @ Mult(a, b)) | (binOp @ Div(a, b)) => ...

有一件事我没有尝试过,与嵌套函数重载,这似乎是矫枉过正...

是在场景中有一个很好的方式匹配多案例类类似于上面的?

注意:在继承中添加额外的方法,类,特征很好。

+0

我已经删除了我的答案,因为它不能解决您的问题,但请注意具体类是必需的,因为抽象类不能实例化,如果您想要删除抽象修饰符。 – 2014-09-21 08:02:49

回答

2

错误消息的提示是要做到:

scala> object Binary { def unapply(e: Mult) = Mult.unapply(e) ; def unapply(e: Div) = Div.unapply(e) } 
defined object Binary 

scala> Div(null,null) match { case Binary(a,b) => (a,b) } 
res3: (DoubleE, DoubleE) = (null,null) 

对不起,要睡在这里,这将是更好的表述为unapply(b: Binary)DoubleE.unapply(d: DoubleE)这对亚型匹配。