F-Bounded多态类型和非泛型子类型的存在类型?

时间:2015-02-23 13:04:23

标签: scala types polymorphism existential-type subtype

我有两个子类型,我需要通过类型A进行F-bounded多态,以及其中一个子类型的子类型,即

trait A[T <: A[T]] {
  def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter

接下来我尝试实现具体类型

case class F2(l: List[A[_]]) extends For {
  def x: For = F2(l.map(_.x))
}

但这无法编译:

<console>:11: error: type mismatch;
 found   : List[Any]
 required: List[A[_]]
         def x: For = F2(l.map(_.x))
                              ^

所以,谷歌说我需要使用存在类型,这是有道理的,所以我尝试:

import scala.language.existentials

type SomeA = T forSome { type T <: A[T] }

case class F1(l: List[SomeA]) extends For {
  def x: For = F1(l.map(_.x))
}

但是,当我尝试实例化

时,我现在面临一个新问题
trait Example {
  val b: Ter
  val c: C
  val d: For

  // Works fine
  val l1: List[A[_]] = List(b, c, d)
  // But this doesn't work, fails to compile (see below)
  val l2: List[SomeA] = List(b, c, d)

  val f1 = F1(l2)
}

编译错误:

<console>:22: error: type mismatch;
 found   : C
 required: SomeA
    (which expands to)  T forSome { type T <: A[T] }
         val l2: List[SomeA] = List(b, c, d)
                                       ^

为什么会出现此错误?当然CTer的子类型,而A[Ter]的子类型又是C的子类型,因此A[Ter]T的子类型,因此存在{ {1}}即TerC是[{1}}的子类型,因此A[T]C的子类型。

好像子类型的传递性不起作用。当我使用SomeA进行攻击时,我的代码编译并且我的单元测试通过。它可能是编译器错误吗?

我还认为c.asInstanceOf[SomeA]的输入强于List[A[_]],即前者说该列表包含List[SomeA]某些已修复的类型{{1} },后者表示该列表包含A[T],其中T 未修复

BOUNS 如果您可以解释为什么当前接受的答案有效,那么为什么编译器无法确定该类型在没有归属的情况下有效。

1 个答案:

答案 0 :(得分:1)

我想编译器需要一些帮助。以下应该有效:

val l2 = List[SomeA](b, c: Ter, d)