I know that "union types" are not supported in Scala, but what about intersection types?
In short, I would like a function like this:
def intersect[A,B,C](a: A, b: B): C = ??? // a & b
Or a method :
class A {
def intersect[B, C](b: B): C = ??? // this & b
}
A
and B
share a common superclass ensuring the validity of the intersect operation, and C
would be a type at the intersection ofA
or B
.
In my use case, A or B represent either variables or constants (of the same type). I want to distinguish, class-wise, a constant from a variable with singleton domain. If I try to intersect a set with a value, I return the value (or return the empty set/throw an exception if the value is not in the set).
Here is an example of expected output:
trait IntExpression {
// Correct signature to be determined
def intersect [A <: IntExpression, B <: A & this.type] (that: A): B
}
case class IntVariable(domain: Seq[Int]) extends IntExpression
case class IntConstant(value: Int) extends IntExpression
val a = IntVariable(1,2,3)
val b = IntVariable(2,3,4)
val c = IntConstant(2)
And then:
a intersect b == b intersect a == IntVariable(2,3)
a intersect c == c intersect a == IntConstant(2)