scala - 从 Scala 中的类型检查中删除路径依赖

标签 scala types path-dependent-type

假设我们有这些嵌套类和 A 的实例化:

class A {
  case object B
  case class C(c: Int)
}
val a1 = new A()

现在我可以检查 a1.Ba1.B.type 的实例,但是如何检查 a1.B< 的类型any A#B.type 的实例,因为编译器不会接受该语法。

a1.B.isInstanceOf[a1.B.type]
res: Boolean = true

a1.B.isInstanceOf[A#B.type]
<console>:1: error: ']' expected but '.' found.
a1.B.isInstanceOf[A#B.type]
                     ^

对于案例类,它似乎可以正常工作:

a1.C(0).isInstanceOf[a1.C]
res: Boolean = true

a1.C(0).isInstanceOf[A#C]
res: Boolean = true

后续问题:当我有

val a1 = new A()
val a2 = new A()

是否有一个函数可以在不考虑路径依赖的情况下进行相等性检查?例如。比较 a1.Ba2.B 时,它应该返回 true。例如:

a1.B =#= a2.B
true

a1.C(0) =#= a2.C(0)
true

a1.C(0) =#= a2.C(1)
false

编辑:澄清一下:仅仅引入 B 的共同特征是不够的,因为我希望能够区分 case 对象:

class A {
    trait BB
    case object B1 extends BB
    case object B2 extends BB
}
val a1 = new A
val a2 = new A

a1.B1 =#= a2.B1 // should be true
a1.B2 =#= a2.B2 // should be true
a1.B1 =#= a1.B2 // should be false
a1.B1 =#= a2.B2 // should be false

现在,.hashCode(或.##)方法似乎可以解决问题:

a1.B1.## == a2.B1.## // true
a1.B1.## == a2.B2.## // false

但也许有一个更优雅的解决方案(例如,我还希望能够在模式匹配中使用 a1.B1)。

最佳答案

只需使用完整形式来表达存在类型。

这是您的示例:

class A {
  case object B1
  case object B2
  case class C(c: Int)
}
val a1 = new A()

我添加了另一个 case 对象来证明它们可以区分,因此我没有为 AnyRef 编写一个晦涩的等效项

type AB1 = a.B1.type forSome {val a : A}
type AB2 = a.B2.type forSome {val a : A}

scala> a1.B1.isInstanceOf[AB1]
res0: Boolean = true

scala> a1.B1.isInstanceOf[AB2]
res1: Boolean = false

为了方便起见,我引入了类型别名 AB1AB2。但如果需要的话,这些类型可以内联到 isInstanceOf 中。

关于scala - 从 Scala 中的类型检查中删除路径依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668915/

相关文章:

list - OCaml:可以包含两种类型的列表?

haskell - 发生检查: cannot construct the infinite type

c# - 将简单对象转换为简单通用的接口(interface)

scala - 为什么 Scala 中的高阶统一被认为是部分的?

scala - "case"在 Scala 的部分函数中究竟是如何工作的?

Scala 有序优先级队列,始终以最低编号作为头,升序排列

scala - scala 中的抽象类型

java - Scala vs Java 性能(HashSet 和二元语法生成)

具有额外约束的 Scala 无形 KList

scala - scala中不同路径依赖类型的特点