继承由内部类型参数化的类

时间:2020-09-28 15:12:35

标签: scala generics types

我想拥有一个类B,该类继承自一个内部类型为A的通用类B。具体来说,我想要这个(最小示例):

class A[T]
class B extends A[T] {
  class T
}

这样编写,编译器不接受。有什么方法可以指定这种继承关系吗? (使用一些不同的语法或技巧)。

如果没有,那么什么是官方参考文件证明这是不可能的?

注释:

  • 是的,我希望T成为内部类。我确实希望B的单独实例具有不兼容的类型T

  • This question考虑​​了相同的情况,但不询问是否/如何可行,而是要求其他方式编写相同的东西。 (至少这就是答案的解释方式。)无论如何,这个问题已有十年历史了,Scala从那以后可能就发展了。

  • 说明::我希望B继承自A,而不是继承自A的内部类,或拥有{ {1}}继承自B。原因是我想在以下情况下使用它:A是类型类。 A应该提供一种快速的方法来轻松生成该类型类的新类(使用最少的样板)。我希望该类的用户执行类似的操作:B,然后他们将能够使用类型implicit val X = createBInstance(),它将具有类型类X.T。到目前为止,我设法做到最好的就是支持模式A并使用val X = createBInstance(); implicit val xTypeclass = X.typeclass。这意味着更多样板,忘记某些东西的可能性,并且更污染命名空间(附加名称X.T)。 (非常好奇:xTypeclassAMLValue.ConverterB,而QuickConverterX / Header /。 .. in my code。)

1 个答案:

答案 0 :(得分:3)

您可以尝试

class A {
  type T
}
class B extends A {
  class T
}

val b: B = new B
val t: b.T = new b.T

我将T设置为类型成员,而不是类型参数。

在这里,一个类覆盖了一个类型。

如果您还想将T用作类型参数,则可以引入Aux-type

object A {
  type Aux[_T] = A { type T = _T }
}

,并使用类型A.Aux[T]代替您原来的A[T]


现在您正在做

trait A[X]

class B {
  class T

  /*implicit*/ object typeclass extends A[T]
}

val b = new B
implicit val b_typeclass: b.typeclass.type = b.typeclass

val b1 = new B
implicit val b1_typeclass: b1.typeclass.type = b1.typeclass

implicitly[A[b.T]]
implicitly[A[b1.T]]

请注意,使对象typeclass隐式变为无用。

如果您将typeclassb对象而不是值制成对象,则将对象b1隐含起来将很有用

trait A[X]

class B {
  class T

  implicit object typeclass extends A[T]
}

object b extends B
object b1 extends B

implicitly[A[b.T]]
implicitly[A[b1.T]]

如果您想使B扩展A,那么我提议将A的类型参数替换为类型成员。 A仍然是类型类,只是类型成员类型类而不是类型参数类型类

trait A {
  type X
}

object A {
  type Aux[_X] = A {type X = _X}
}

class B extends A {
  type X = T

  class T
}

implicit object b extends B
implicit object b1 extends B

implicitly[A.Aux[b.T]]
implicitly[A.Aux[b1.T]]