【问题标题】:Scala -- multiple F-bounded types in inheritance treeScala - 继承树中的多个 F 有界类型
【发布时间】:2016-10-01 18:54:25
【问题描述】:

我在 Scala 中有一个通用的 F-bounded trait。让我编写返回相同底层实现类型的方法,超级!但是现在让我们说一个子特征 also 定义了需要 F-bounding 的方法。 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]

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

【问题讨论】:

    标签: scala polymorphism f-bounded-polymorphism


    【解决方案1】:

    约束需要AnyComplexImpl 来实现FBounded[AnyComplexImpl],它不需要,而不仅仅是FBounded[T] forSome { type T &lt;: ComplexImpl[T] }

    如果你使 FBoundedComplexImpl 协变,它会起作用。编译器的原因是:

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

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

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

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

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

    【讨论】:

    • 啊哈!协/逆变是我仍在试图更好地掌握的类型系统的一个角落。谢谢。
    猜你喜欢
    • 2016-09-22
    • 2015-03-09
    • 1970-01-01
    • 2018-06-08
    • 2015-06-03
    • 2018-05-20
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    相关资源
    最近更新 更多