假设我有两个特征:
trait Generic1[T] {
def mapR[U](f: Result[T] => Result[U]): Generic1[U]
}
trait Generic2[A, T] {
// pretty much the same as Generic1, but with the extra `A` type param
def mapR[U](f: Result[T] => Result[U]): Generic2[A, U]
}
有没有办法可以定义一个基于mapR
方法定义一些常用功能的特征?
// for example
trait MapR[T, ???] {
def mapR[U](f: Result[T] => Result[U]): ???[U]
def map[U](f: T => U): ???[U] = mapR(_ map f)
def flatMap[U](f: T => Result[U]): ???[U] = mapR(_ flatMap f)
def withFilter(f: T => Boolean): ???[T] = mapR(_ withFilter f)
}
如何在上面的???
特征中定义MapR
,以便我可以改为定义
trait Generic1[T] extends MapR[T, ???]
trait Generic2[A, T] extends MapR[T, ???]
额外问题
@ m-z的答案处理上面提到的问题,但是当GenericN特征具有类型差异时,我遇到了一些麻烦:
trait Generic1[+T] extends MapR[T] {
type R[X] = Generic1[X]
...
}
trait Generic2[-A, +T] extends MapR[T] {
type R[X] = Generic2[A, X]
...
}
我得到类似“逆变类型A出现在类型为[X] Generic2 [A,X]中的不变位置”的错误
我尝试重新定义R是协变的,但它仍然没有触及A
类型,我也遇到了类似的错误。
答案中的方法是否可以调整以处理上述的类型差异?
答案 0 :(得分:2)
您可以使MapR
特征具有单个类型参数的类型成员,而不能实现Generic
特征的别名。这将需要每个Generic
特征来描述它的参数化方式。
trait Result[T]
trait MapR[T] {
type R[U]
def mapR[U](f: Result[T] => Result[U]): R[U]
}
trait Generic1[T] extends MapR[T] {
type R[U] = Generic1[U]
}
trait Generic2[A, T] extends MapR[T] {
type R[U] = Generic2[A, U]
}
答案 1 :(得分:1)
你可能可以通过宣布超高级管理来实现这一目标。沿着这些方向的东西可能是可能的:
trait Result[T]
trait MapRSupport[SelfType[X], T] {
def mapR[U](f: Result[T] => Result[U]): SelfType[U]
}
trait Generic1[T] extends MapRSupport[Generic1, T]{
def mapR[U](f: Result[T] => Result[U]): Generic1[U] = ???
}
trait Generic2[A] extends MapRSupport[Generic2, A]{
type T
// pretty much the same as Generic1, but with the extra `A` type param
def mapR[U](f: Result[T] => Result[U]): Generic2[A] { type T = U} = ???
}