sam*_*est 5 polymorphism types scala existential-type subtype
我有两个子类型,我需要通过类型进行F-有限多态A,以及其中一个子类型的子类型,即
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Run Code Online (Sandbox Code Playgroud)
接下来我尝试实现一个具体类型
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
Run Code Online (Sandbox Code Playgroud)
但这无法编译:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
Run Code Online (Sandbox Code Playgroud)
所以,谷歌说我需要使用存在类型,这是有道理的,所以我尝试:
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))
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试实例化时,现在我遇到了一个新问题
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)
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
<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)
^
Run Code Online (Sandbox Code Playgroud)
为什么我会收到此错误?当然C是的一个亚型Ter,而这又是的一个亚型A[Ter],因此C是的一个亚型A[Ter],因此存在一个T即Ter,使得C是的子类型A[T],因此C是的子类型SomeA.
就好像子类型的传递性不起作用.当我用c.asInstanceOf[SomeA]我的代码编译破解它并且我的单元测试通过.它可能是编译器错误吗?
我还以为List[A[_]]比打字强List[SomeA],即前者是说名单包括A[T]一些固定的类型T,其中后者称该列表由A[T]地方T是不固定的.
BOUNS如果您可以解释为什么当前接受的答案有效,即为什么编译器无法确定该类型在没有归属的情况下有效.
小智 1
我想编译器需要一些帮助。以下应该有效:
val l2 = List[SomeA](b, c: Ter, d)
Run Code Online (Sandbox Code Playgroud)