这不会输入:
sealed trait Binop[-InA,-InB,+Out] case object Add extends Binop[Int,Int,Int] 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) }
最直接的事情是在模式匹配中使用case对象:
[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(b)) => IntegerAtom(a + b)
但是之后:
[error] (...) type mismatch; [error] found : minimumexample.IntegerAtom [error] required: minimumexample.Expression[A] [error] case BinaryExp(AddOp,IntegerAtom(b)) => IntegerAtom(a + b) [error] ^
我想尽可能安全地解决这个问题,而不是诉诸.asInstanceOf [].思考?
解决方法
您的代码的主要问题是BinaryExp定义中的差异问题,但这似乎不在问题的范围内.一旦你修正了方差,你就会遇到案例对象不引入新类型的唯一不便.
解决此问题的典型模式是声明一个密封特征,然后有一个案例对象来扩展它.
这是一个编译的例子
sealed trait Binop[-InA,+Out] sealed trait Add extends Binop[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,C](op: Binop[A,rhs: Expression[B]) extends Expression[C] def optimizeStep[A](x: Expression[A]): Expression[A] = x match { case BinaryExp((_: Add),IntegerAtom(b)) => IntegerAtom(a + b) }
哪里:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。