Scala——继承树中的多个f边界类型



我在Scala中有一个通用的F-bounded trait。让我来编写返回相同底层实现类型的方法,super!现在让我们假设一个子性状定义了需要f边界的方法。Scala给我返回了一些没有意义的编译错误:

package sandbox
import sandbox.ComplexImpl.AnyComplexImpl
import scala.language.existentials
trait FBounded[IMPL <: FBounded[IMPL]] { self: IMPL =>
  def foo: IMPL
}
trait FBoundedUser[F <: FBounded[F]] {
  def bar(value: F): F = value.foo
}
trait SimpleImpl extends FBounded[SimpleImpl] {
  override def foo: SimpleImpl = this
}
object SimpleUser extends FBoundedUser[SimpleImpl]
// A-OK so far...
trait ComplexImpl[IMPL <: ComplexImpl[IMPL]] extends FBounded[IMPL] { self: IMPL =>
  def baz: IMPL
}
object ComplexImpl {
  type AnyComplexImpl = ComplexImpl[T] forSome { type T <: ComplexImpl[T] }
}
object ComplexUser1 extends FBoundedUser[ComplexImpl[_]]
object ComplexUser2 extends FBoundedUser[AnyComplexImpl]

尝试使用ComplexUser1ComplexUser2进行编译会导致:

Error:(32, 29) type arguments [sandbox.ComplexImpl.AnyComplexImpl] do not conform to trait
               FBoundedUser's type parameter bounds [F <: sandbox.FBounded[F]]

这对我来说没有意义。AnyComplexImpl完全实现了FBounded。是我遗漏了什么,还是类型检查器在这里失败了?

编辑:

class Concrete() extends ComplexImpl[Concrete] {
  override def baz: Concrete = this
  override def foo: Concrete = this
}
object ComplexUser3 extends FBoundedUser[Concrete]

编译得很好。那么为什么通用版本不能呢?

约束要求AnyComplexImpl实现FBounded[AnyComplexImpl],而不是FBounded[T] forSome { type T <: ComplexImpl[T] }

如果使FBoundedComplexImpl协变,则有效。编译器认为:

  1. AnyComplexImpl是任何ComplexImpl[T]的超类型,其中T <: ComplexImpl[T];

  2. 所以FBounded[T] forSome { type T <: ComplexImpl[T] }FBounded[AnyComplexImpl]的子类型;

  3. 所以AnyComplexImplFBounded[AnyComplexImpl]的子类型

但是我怀疑尝试混合f有界类型和存在可能会导致其他问题。ComplexUser1ComplexUser2不能编译的原因恰恰是它们不是泛型的。考虑使用真正的通用版本:

def complexUser4[T <: ComplexImpl[T]] = new FBoundedUser[T] {}

最新更新