Scala中的“交集类型”

时间:2013-10-17 14:09:40

标签: scala types intersection

我知道Scala不支持“联合类型”,但交集类型呢?

简而言之,我想要一个像这样的函数:

def intersect[A,B,C](a: A, b: B): C = ??? // a & b

或方法:

class A {
    def intersect[B, C](b: B): C = ??? // this & b
}

AB共享一个共同的超类,确保交叉操作的有效性,C将是A或{{1}的交叉点的类型}。

在我的用例中,A或B表示变量或常量(相同类型)。我想区分一个常量,一个变量与一个单独的域。如果我尝试将一个值与一个值相交,我将返回该值(如果该值不在该集合中,则返回空集/抛出异常)。

以下是预期输出的示例:

B

然后:

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)

2 个答案:

答案 0 :(得分:2)

由于上面正确说明了ziggystar:Scala中A & BA with B

关于您想在运行时创建伴随类型C的事实,您必须根据AB中的类型在运行时创建此类型。

您可以在How to mix-in a trait to instance?找到解决方案,或者至少是一个线索。

但是,您在用例中想要的是http://en.wikipedia.org/wiki/Dependent_type的情况。尽管Scala不支持依赖类型,但您可以尝试使用Agda;)

答案 1 :(得分:0)

我使用++作为实现,因为它就在那里。 intersect上的Set不起作用,因为Set是不变的。如果这没有意义,请忽略它。

def intersect[C, A <: C, B <: C](as: Seq[A], bs: Seq[B]): Seq[C] = as ++ bs