This doesn't type:
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)
}
The most immediate thing is the usage of a case object in pattern match:
[error] (...) pattern type is incompatible with expected type;
[error] found : minimumexample.Add.type
[error] required: minimumexample.BinOp[Any,Any,A]
It seems that this can be solved by introducing the eye-bleeding:
val AddOp = Add
And then:
case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b)
But then:
[error] (...) type mismatch;
[error] found : minimumexample.IntegerAtom
[error] required: minimumexample.Expression[A]
[error] case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b)
[error] ^
I want to solve this as type-safely as possible, without resorting to .asInstanceOf[]. Thoughts?
The main issue with your code is a variance issue in the definition of BinaryExp, but that doesn't seem in scope of the question. Once you get the variance fixed, you're left with the only inconvenience that case object does not introduce a new type.
A typical pattern for solving this issue is to declare a sealed trait and then have a case object to extend it.
Here's an example that compiles
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)
}
where:
Add is now a type thanks to the sealed trait definition(_: Add)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With