参数化特征可以指定其抽象类之一返回与实现类相同类型的值吗?

时间:2017-06-12 23:43:50

标签: scala

说我有这样的特质:

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的要求。这可能吗?

3 个答案:

答案 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定义为不是自己的东西,但我不知道任何解决方案(这是一个常见的问题)。