【问题标题】:Is it possible to equal abstract type members in Scala?Scala中的抽象类型成员是否可以相等?
【发布时间】:2023-03-04 16:55:01
【问题描述】:

泛型类型参数优于抽象类型成员的一个优势似乎是前者可以相等,例如:

trait A[X]
trait B[Y]
trait C[Z] extends A[Z] with B[Z]

同样:

trait C[Z] {
    self: A[Z] with B[Z] =>
}

类型参数的赋值实际上说明了三件事:X = Z,Y = Z,因此 X = Y。

第一种情况可以类推:

trait A { type X }
trait B { type Y }
class C extends A with B { type X = Z; type Y = Z; type Z }

但是,抽象类型成员是否可能出现第二种情况?以下解决方案不起作用,因为不能从自身类型定义中引用类型“Z”,而自身类型定义必须先出现:

trait C {
  self: A with B { type X = Z; type Y = Z } =>
  type Z
}

奇怪的是,即使明显违反了“b”的类型要求,以下内容似乎也可以编译:

trait C2 {
    val a: A { type X = Z }
    val b: B { type Y = Z }
    type Z
}

class A2 extends A { type X = Int }
class B2 extends B { type Y = String }
class D extends C2 {
    override val a = new A2
    override val b = new B2
    type Z = Int
}

【问题讨论】:

    标签: scala types abstract


    【解决方案1】:

    您可以使用类型参数相等的见证,=:=scalaz.Leibniz.===(更通用,但意味着取决于 scalaz)。

    class C extends A with B { type Z; val w1: X =:= Z; val w2: Y =:= Z }
    

    如果类型不相等,则无法实例化它,您可以使用w1w2XY类型的值“转换”为Z类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      相关资源
      最近更新 更多