[英]scala: Referencing Trait with F-Bound Parameters
I am designing a F-Bound data type, and have a working companion object. 我正在设计一个F-Bound数据类型,并具有一个正常工作的伴随对象。 I would like to reference this companion object from the trait itself, but I can't get the types right.
我想从特征本身中引用此伴侣对象,但是我无法正确获得类型。
trait A[AA <: A[AA]] {
self =>
val data: String
}
case class A1(data : String) extends A[A1]
trait B[BB <: B[BB, AA], AA <: A[AA]] {
self: BB =>
val content: AA
def companion: BComp[BB, AA] // What is the correct type?
def companion2: BComp2[BB, AA] // What is the correct type?
}
trait BComp[BB[X <: BB[X, AA], Y <: AA[Y]], AA[Y <: AA[Y]]]
trait BComp2[BB[X <: AA[X]], AA[X <: AA[X]]]
case class BInst[AA <: A[AA]](content: AA) extends B[BInst[AA], AA] {
def companion = BInst
def companion2 = BInst2
}
object BInst extends BComp[B, A]
object BInst2 extends BComp2[BInst, A]
A working solution for either companion
or companion2
would suffice, although a general hint on how to construct these type signatures would be useful. 尽管对于如何构造这些类型签名的一般提示将很有用,但是可以为
companion
或companion2
提供一个companion
解决方案。
edit 编辑
I want to use the companion object to store canBuildFrom
style implicits as well as Builders, but as the content type A
has an upper bound, all generating functions need to be aware of this bounding, so hence the parametrization of the companion object trait. 我想使用随
canBuildFrom
对象来存储canBuildFrom
样式隐式对象以及Builders,但是由于内容类型A
具有上限,所有生成函数都需要意识到这一边界,因此,对随播对象特征进行参数化。 The inspiration for this design comes from GenericCompanion.scala , of course, adding the type bounds makes everything more difficult :P 这种设计的灵感来自GenericCompanion.scala ,当然,添加类型边界会使一切变得更加困难:P
The obstacle to any clear definition of types for companion
is that BComp
is parametrized by two parametrized types - while the first one is compatible with B
, the second one AA[Y <: AA[Y]]
is impossible to construct. 不能明确定义
companion
类型的障碍是BComp
由两种参数化类型进行了参数化 -第一种与B
兼容,而第二种AA[Y <: AA[Y]]
无法构造。 So quite simply, we need to add this type to the parametrization of B
: 很简单,我们需要将此类型添加到
B
的参数化中:
trait B[BB <: B[BB, AA, X],
AA[T <: AA[T]] <: A[T],
X <: AA[X]] {
self: BB =>
val content: X
def companion: BComp[B, AA]
}
now we have a compatible type AA
for our companion object (which needs only a small expansion): 现在,我们为伴随对象提供了兼容的
AA
类型(只需要进行小扩展):
trait BComp[BHere[BB <: BHere[BB, AAA, Z],
AAA[Y <: AAA[Y]],
Z <: AAA[Z]],
AA[Y <: AA[Y]]]
Isn't that pretty? 那不是很漂亮吗?
case class BInst[X <: A[X]](content: X) extends B[BInst[X], A, X] {
def companion: BComp[B, A] = BInst5
}
object BInst extends BComp[B, A]
companion2
For companion2
, we just need to change the first part of the parametrization of B
, so that trait B
and the companion trait become: 对于
companion2
,我们只需要更改B
的参数化的第一部分,以使特征B
和伴随特征变为:
trait B[BB[TS <: AA[TS]] <: B[BB, AA, TS],
AA[T <: AA[T]] <: A[T],
X <: AA[X]] {
self: BB[X] =>
val content: X
def companion2: BComp[BB, AA]
}
trait BComp[BHere[TS <: AA[TS]],
AA[Y <: AA[Y]]]
This is slightly more manageable. 这稍微更易于管理。 The case class and case objects are:
案例类和案例对象为:
case class BInst[X <: A[X]](content: X) extends B[BInst, A, X] {
def companion2: BComp[BInst, A] = BInst5
}
object BInst extends BComp[BInst, A]
If this is useful to anybody the rethink. 如果这对任何人都有用,请重新考虑。 I have changed my own design approach and I suggest you do too.
我已经更改了自己的设计方法,建议您也这样做。 Coming up with a solution to these types has now been a purely academic exercise!
提出针对这些类型的解决方案现在纯粹是一项学术工作!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.