Scala——继承树中的多个 F 有界类型

Scala -- multiple F-bounded types in inheritance tree

我在 Scala 中有一个通用的 F 有界特征。让我编写 return 相同底层实现类型的方法,超级!但是现在假设子特征 also 定义了需要 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] {}