我有一个相互平行的类型层次结构,这些层次结构通常相互引用:一个通过普通泛型,另一个通过类型变量。
但是,并行层次结构之一比另一个层次结构短,这导致了我的麻烦。
我在下面提供了一个代码段,并将编译器错误作为行内注释添加到导致问题的行上方:
type arguments [Foo[_],FooKey] do not conform to trait PrimaryKey's type parameter bounds [A <: Entity[A],B <: PrimaryKey[A,B]]
overriding type K in trait Entity with bounds <: PrimaryKey[A,Foo.this.K]; type K has incompatible type
问题是我希望FooKey
不通用,因为FooKey
对于参数Foo
的实现有多精确都无关紧要。
package com.scalatest
object Database {
trait PrimaryKey[A <: Entity[A], B <: PrimaryKey[A, B]] {
this: B =>
}
trait Entity[A <: Entity[A]] {
this: A =>
type K <: PrimaryKey[A, K]
val id: K
}
//Error:(17, 24) type arguments [com.scalatest.Database.Foo[_],com.scalatest.Database.FooKey] do not conform to trait PrimaryKey's type parameter bounds [A <: com.scalatest.Database.Entity[A],B <: com.scalatest.Database.PrimaryKey[A,B]]
// class FooKey extends PrimaryKey[Foo[_], FooKey]
class FooKey extends PrimaryKey[Foo[_], FooKey]
trait Foo[A <: Foo[A]] extends Entity[A] {
this: A =>
//Error:(24, 19) overriding type K in trait Entity with bounds <: com.scalatest.Database.PrimaryKey[A,Foo.this.K];
// type K has incompatible type
// override type K = FooKey
override type K = FooKey
}
class FooImpl(val id: FooKey) extends Foo[FooImpl]
}
我设法在声明Foo[_]
中使用了存在性类型而不是FooKey
,同时使所有A
协变,但是我仍然遇到第二个错误
class FooKey extends PrimaryKey[Foo[A] forSome { type A <: Foo[A] }, FooKey]
答案 0 :(得分:1)
那不是真的
对于
FooKey
来说,Foo
的实现参数的准确程度无关紧要。
您要使用FooKey
覆盖类型K <: PrimaryKey[A, K]
,其中A
与trait Entity[A <: Entity[A]] {...
中的类型相同
而且您在trait Foo[A <: Foo[A]] {...
中进行了覆盖,因此FooKey
必须满足条件K <: PrimaryKey[A, K]
(这不仅是上限,因为K
在两端都存在) },因此A <: Foo[A]
应该被普遍地量化而不是存在地量化。
因此您应该将类型参数添加到FooKey
FooKey