在 Scala 类型层次结构中途忽略通用参数
Ignoring generic argument halfway through scala type hierarchy
我有一个平行的类型层次结构,它们通常相互引用:一个通过普通泛型,另一个通过类型变量。
但是,其中一个并行层次结构比另一个短,这给我带来了问题。
我在下面提供了一个代码片段,编译器错误被添加为导致问题的行上方的内联注释:
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]
}
我设法在我的 FooKey
声明中使用存在类型而不是 Foo[_]
,同时使所有 A
协变,但我仍然剩下第二个错误。
class FooKey extends PrimaryKey[Foo[A] forSome { type A <: Foo[A] }, FooKey]
这不是真的
for FooKey
it doesn't matter how exactly the implementation of Foo
is parameterized.
您想用 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
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
}
class FooKey[A <: Foo[A]] extends PrimaryKey[A, FooKey[A]]
trait Foo[A <: Foo[A]] extends Entity[A] {
this: A =>
override type K = FooKey[A]
}
class FooImpl(val id: FooKey[FooImpl]) extends Foo[FooImpl]
}
我有一个平行的类型层次结构,它们通常相互引用:一个通过普通泛型,另一个通过类型变量。
但是,其中一个并行层次结构比另一个短,这给我带来了问题。
我在下面提供了一个代码片段,编译器错误被添加为导致问题的行上方的内联注释:
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]
}
我设法在我的 FooKey
声明中使用存在类型而不是 Foo[_]
,同时使所有 A
协变,但我仍然剩下第二个错误。
class FooKey extends PrimaryKey[Foo[A] forSome { type A <: Foo[A] }, FooKey]
这不是真的
for
FooKey
it doesn't matter how exactly the implementation ofFoo
is parameterized.
您想用 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
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
}
class FooKey[A <: Foo[A]] extends PrimaryKey[A, FooKey[A]]
trait Foo[A <: Foo[A]] extends Entity[A] {
this: A =>
override type K = FooKey[A]
}
class FooImpl(val id: FooKey[FooImpl]) extends Foo[FooImpl]
}