3

我知道 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将是Aor的交集处的类型B

在我的用例中,A 或 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)

接着:

a intersect b == b intersect a == IntVariable(2,3)
a intersect c == c intersect a == IntConstant(2)
4

2 回答 2

2

正如上面正确说明的 ziggystar:A & BA with BScala 中。

关于您要C在运行时创建伴随类型的事实,您必须要在运行时创建此类型,基于您在A和中获得的类型B

对此的解决方案,或者至少是一个线索,您可以在如何将特征混合到实例中找到?.

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

于 2013-10-17T22:59:54.637 回答
0

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

def intersect[C, A <: C, B <: C](as: Seq[A], bs: Seq[B]): Seq[C] = as ++ bs
于 2013-10-17T15:42:04.510 回答