说我有这样的特质:
trait BaseTrait[A] {
def someMethod[B](f: A => T[B]): T[B]
}
我希望T
基本上是“与实现此方法的类相同的类型”。换句话说,我希望能够写下这个:
class ConcreteClass[A] extends BaseTrait[A] {
def someMethod[B](f: A => ConcreteClass[B]): ConcreteClass[B]
}
并且该方法满足特征对someMethod
的要求。这可能吗?
答案 0 :(得分:8)
您所询问的是F-bound类型,这是我在该主题上看到的最佳解释: https://tpolecat.github.io/2015/04/29/f-bounds.html
一句话就是你要么想要切换到使用类型而不是继承,或者你必须满足于几乎一直到你想要的东西,如下所示:
$product->get_id()
现在,在您的情况下,您的特征本身需要一个类型参数,因此您还必须使用其他类型参数,并使用更高级的类型,如下所示:
trait BaseTrait[A <: BaseTrait[A]] { this: A =>
def someMethod[B](f: A => T[B]): T[B]
}
class Concrete extends BaseTrait[Concrete]{
def someMethod[B](f: A => T[B]): T[B]
}
答案 1 :(得分:3)
也许是这样的?:
trait BaseTrait[M[_], A] { self: M[A] =>
def someMethod[B](f: A => M[B]): M[B]
}
class ConcreteClass[A] extends BaseTrait[ConcreteClass, A] {
def someMethod[B](f: A => ConcreteClass[B]): ConcreteClass[B] = ???
}
我认为让它变得更具体是很难的。
答案 2 :(得分:1)
这是使用类型成员而不是类型参数的版本。我认为这取决于你喜欢的个人偏好。
trait BaseTrait[A] {
type Self[X] <: Base[X]
def doSomething[B](f: A => Self[B]): Self[B]
}
class ConcreteClass[A] extends BaseTrait[A] {
type Self[X] = ConcreteClass[X]
def doSomething[B](f: A => ConcreteClass[B]): ConcreteClass[B] = ???
}
它不会阻止一些具体的实现,将Self
定义为不是自己的东西,但我不知道任何解决方案(这是一个常见的问题)。