在mixin上推断类型参数

时间:2019-01-04 17:23:28

标签: scala

假设我有一些特征:

trait A[T] { def foo: T }

扩展它的类:

class B[T](t: T) extends A[T] { def foo = t }

以及父特征的子特征:

trait C[T] extends A[T]

我想将C和B混在一起。

val foo = new B("foo") with C[String]

这很好用,但是我不想再指定类型参数,因为B已经是类型A [String]。但是,我知道Scala不支持以下内容:

val foo = new B("foo") with C

我的问题是类型系统中还有其他机制可以支持在混合C时不必指定类型参数。我在想的是:

trait C {
  self: A[T] => ...
}

人们会认为这种事情可以解决C可能混入的问题。但是,它不是有效的Scala。像这样:

trait C {
  type T
  self: A[T] =>
}

也不起作用。

2 个答案:

答案 0 :(得分:1)

如何?

scala> trait C {
     |   self: A[_] => 
     | }
defined trait C

scala> val foo = new B("foo") with C
foo: B[String] with C = $anon$1@f2df380

scala> foo.foo
res16: String = foo

答案 1 :(得分:1)

您可以使用抽象类型来做到这一点:

  trait A {
    type AT
    def foo: AT
  }

  class B[T](t: T) extends A {
    type AT = T 
    def foo = t
  }

  trait C extends A

  val foo = new B("foo") with C

定义稍微冗长一些,但是满足了您不必再次键入T的要求。