如何声明一个特征等同于给定类型参数的另一个通用特征?
How to state one trait is the equivalent of another generic trait for a given type parameter?
我有一个通用特征
trait MyTrait[T] {
def apply(t: T): T
def compose(e: MyTrait[T]): MyTrait[T]
}
还有另一个为特定类型实现此特征的特征...
trait IntTrait extends MyTrait[Int] {
override def compose(e: MyTrait[Int]): MyTrait[Int]
}
现在,尽管这不是什么大不了的事,但主要是美学问题;我希望能够说...
trait IntTrait extends MyTrait[Int] {
override def compose(e: IntTrait): IntTrait
}
但这打破了 MyTrait 方法的契约,因为它承诺在 all MyTrait[Int] 上定义,而 IntTrait,就编译器所知,是只是 MyTrait[Int] 的一个适当子集。所以我想做的基本上就是告诉编译器 IntTrait IS MyTrait[Int]。换句话说,没有不是 IntTraits 的 MyTrait[Int]。
我想我可以通过
完成这个
trait IntTrait extends MyTrait[Int] {
type IntTrait = MyTrait[Int]
override def compose(e: IntTrait): IntTrait
}
哪个有效! ...有点,但是如果我尝试在其他地方使用它...
trait doesStuffWithIntTrait {
def foo: IntTrait
}
然后在实现中,我得到了这样的错误...
Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait
有什么想法吗?
Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait
(基于foo
方法)这个错误意味着你的foo
方法return类型是IntTrait
class类型,但您正在 return 使用 类型别名 IntTrait
类型 (IntTrait#IntTrait
).
并且对于 IntTrait IS MyTrait[Int]. 不是真实的,IntTrait
是 subclass 的 MyTrait[Int]
。
为了您的目的,也许您可以这样做:
trait MyTrait[T] {
type K <: MyTrait[T]
def apply(t: T): T
def compose(e: K): K
}
trait IntTrait extends MyTrait[Int] {
type K = IntTrait
override def compose(e: IntTrait): IntTrait
}
So what I'd like to be able to do is basically tell the compiler that IntTrait IS MyTrait[Int]. In other words, that there are no MyTrait[Int]s that are not IntTraits.
这其实是两种截然不同的愿望。首先,您确实想要一个类型别名,但是您将它放在了错误的范围内。删除 trait IntTrait
,添加
object MyTrait {
type IntTrait = MyTrait[Int]
}
(如果您还没有 object MyTrait
)并将其称为 MyTrait.IntTrait
。您也可以将其放在 package object 中。
对于第二个,你无法说服编译器,但遵循@chengpohi 的解决方案(或类似的
trait MyTrait[T, K <: MyTrait[T]] {
def apply(t: T): T
def compose(e: K): K
}
trait IntTrait extends MyTrait[Int, IntTrait] {
override def compose(e: IntTrait): IntTrait
}
) 接近。就其本身而言,它并不能阻止某人也声明 trait IntTrait2 extends MyTrait[Int, IntTrait2]
,但您可以使 MyTrait
sealed
.
我有一个通用特征
trait MyTrait[T] {
def apply(t: T): T
def compose(e: MyTrait[T]): MyTrait[T]
}
还有另一个为特定类型实现此特征的特征...
trait IntTrait extends MyTrait[Int] {
override def compose(e: MyTrait[Int]): MyTrait[Int]
}
现在,尽管这不是什么大不了的事,但主要是美学问题;我希望能够说...
trait IntTrait extends MyTrait[Int] {
override def compose(e: IntTrait): IntTrait
}
但这打破了 MyTrait 方法的契约,因为它承诺在 all MyTrait[Int] 上定义,而 IntTrait,就编译器所知,是只是 MyTrait[Int] 的一个适当子集。所以我想做的基本上就是告诉编译器 IntTrait IS MyTrait[Int]。换句话说,没有不是 IntTraits 的 MyTrait[Int]。
我想我可以通过
完成这个trait IntTrait extends MyTrait[Int] {
type IntTrait = MyTrait[Int]
override def compose(e: IntTrait): IntTrait
}
哪个有效! ...有点,但是如果我尝试在其他地方使用它...
trait doesStuffWithIntTrait {
def foo: IntTrait
}
然后在实现中,我得到了这样的错误...
Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait
有什么想法吗?
Type mismatch, expected: IntTrait, actual: IntTrait#IntTrait
(基于foo
方法)这个错误意味着你的foo
方法return类型是IntTrait
class类型,但您正在 return 使用 类型别名 IntTrait
类型 (IntTrait#IntTrait
).
并且对于 IntTrait IS MyTrait[Int]. 不是真实的,IntTrait
是 subclass 的 MyTrait[Int]
。
为了您的目的,也许您可以这样做:
trait MyTrait[T] {
type K <: MyTrait[T]
def apply(t: T): T
def compose(e: K): K
}
trait IntTrait extends MyTrait[Int] {
type K = IntTrait
override def compose(e: IntTrait): IntTrait
}
So what I'd like to be able to do is basically tell the compiler that IntTrait IS MyTrait[Int]. In other words, that there are no MyTrait[Int]s that are not IntTraits.
这其实是两种截然不同的愿望。首先,您确实想要一个类型别名,但是您将它放在了错误的范围内。删除 trait IntTrait
,添加
object MyTrait {
type IntTrait = MyTrait[Int]
}
(如果您还没有 object MyTrait
)并将其称为 MyTrait.IntTrait
。您也可以将其放在 package object 中。
对于第二个,你无法说服编译器,但遵循@chengpohi 的解决方案(或类似的
trait MyTrait[T, K <: MyTrait[T]] {
def apply(t: T): T
def compose(e: K): K
}
trait IntTrait extends MyTrait[Int, IntTrait] {
override def compose(e: IntTrait): IntTrait
}
) 接近。就其本身而言,它并不能阻止某人也声明 trait IntTrait2 extends MyTrait[Int, IntTrait2]
,但您可以使 MyTrait
sealed
.