繁体   English   中英

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

[英]Can a parameterized trait specify that one of its abstract classes return a value of the same type as implementing classes?

说我有一个这样的特征:

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

您要问的是F绑定类型,这是我在该主题上看到的最好的解释: https : //tpolecat.github.io/2015/04/29/f-bounds.html

最重要的一点是,您要么要切换到使用类型类而不是继承,要么必须适应几乎所有方式,例如:

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]
}

现在,在您的情况下,您的特征本身带有一个类型参数,因此,您还必须使用其他类型参数,并使用像下面这样的高类型类型:

trait BaseTrait[A, T[X] <: BaseTrait[X, T]] { this: T[A] =>
  def someMethod[B](f: A => T[B]): T[B]
}

class Concrete[A] extends BaseTrait[A, Concrete]{
  def someMethod[B](f: A => Concrete[B]): Concrete[B] = ???
}
//class DoesNotCompile[A] extends BaseTrait[Concrete, A]{
//  def someMethod[B](f: A => Concrete[B]): Concrete[B] = ???
//}

//class DoesNotCompile2[A] extends BaseTrait[DoesNotCompile2, A]{
//  def someMethod[B](f: A => Concrete[B]): Concrete[B] = ???
//}

object Ex {
  val concrete: Concrete[List[Int]] = new Concrete[List[Int]]
  val concrete2: Concrete[String] = concrete.someMethod(_ => new Concrete[String])

}

也许是这样的:

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] = ???
}

我认为很难做到比这更具体。

这是使用类型成员而不是类型参数的版本。 我认为这取决于您的个人喜好。

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定义为自身以外的东西,但是我不知道对此有任何解决方案(这是一个普遍的问题)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM