在Scala中键入推理和模式加工

时间:2015-07-15 15:38:32

标签: scala pattern-matching type-inference

这不输入:

[error] (...) pattern type is incompatible with expected type;
[error]  found   : minimumexample.Add.type
[error]  required: minimumexample.BinOp[Any,Any,A]

最直接的是在模式匹配中使用案例对象:

val AddOp = Add

这似乎可以通过引入眼睛出血来解决:

case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b)

然后:

[error] (...) type mismatch;
[error]  found   : minimumexample.IntegerAtom
[error]  required: minimumexample.Expression[A]
[error]     case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b)
[error]                                                                         ^

但是:

.asInstanceOf[]

我希望尽可能安全地解决这个问题,而不是诉诸if (array.Series1 && array.Series1.length) { //Populated } 。想法?

1 个答案:

答案 0 :(得分:5)

您的代码的主要问题是BinaryExp定义中的差异问题,但这似乎不在问题的范围内。一旦你修正了方差,你就会感到case object没有引入新类型的唯一不便。

解决此问题的典型模式是声明sealed trait,然后使用case object来扩展它。

这是一个编译

的例子
sealed trait BinOp[-InA, -InB, +Out]
sealed trait Add extends BinOp[Int, Int, Int]
case object Add extends Add

sealed trait Expression[+A]
final case class IntegerAtom(value: Int) extends Expression[Int]
final case class BinaryExp[A, B, C](op: BinOp[A, B, C], lhs: Expression[A], rhs: Expression[B]) extends Expression[C]

def optimizeStep[A](x: Expression[A]): Expression[A] = x match {
  case BinaryExp((_: Add), IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b)
}

其中:

  • 方差以天真的方式“固定”(将其删除)
  • 由于Add定义,
  • sealed trait现在是一个类型
  • 匹配是使用(_: Add)
  • 执行的