如何用mixin实现F-有界多态?

时间:2016-12-12 06:31:04

标签: scala polymorphism mixins

假设我有一个mixin特性,我想定义一个方法,其返回类型取决于特征混合到的对象的最终类型......

trait MultiUnit extends Quantity {
  this: Order =>

  def split(unmatchedQuantity: Long): (???, ???)

}

...例如,如果我有一个混合在MultiUnit的案例类,我希望返回类型看起来如下......

case class MultiUnitLimitOrder(price: Double, quantity: Long) extends Order with MultiUnit {

  def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ???

}

...如果可能的话,我更喜欢使用类型成员而不是类型参数的解决方案。

2 个答案:

答案 0 :(得分:1)

如果trait Order trait Quantity trait MultiUnit extends Quantity { this: Order => type T <: MultiUnit def split(unmatchedQuantity: Long): (T, T) } case class MultiUnitLimitOrder(price: Double, quantity: Long) extends Order with MultiUnit { override type T = MultiUnitLimitOrder override def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ??? } 的上限足够,你可以这样做:

 r"property\W+({.*?})"

答案 1 :(得分:1)

我不会像你上面提到的那样使用抽象类型的成员,有限的是正确的方式。如果您提前知道T的类型,例如您正在计算类型,则该类型成员模式很有用。当您请求隐式证据时,Shapeless始终使用该模式,例如:

def test[Computed]()(implicit gen: Generic.Aux[Source, Computed]): Result[Computed] = {}

这用于将Generic类内部类型成员的值“转移”到上面的类型参数Computed

在你的情况下,除非绝对必须,否则请保持简单。

trait Order
trait Quantity

trait MultiUnit[T <: MultiUnit[T]] extends Quantity {
  this: Order =>

  def split(unmatchedQuantity: Long): (T, T)
}

case class MultiUnitLimitOrder(price: Double, quantity: Long) 
  extends Order with MultiUnit[MultiUnitLimitOrder] {
    override def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ???
}

我也不明白为什么你需要self-type绑定this: Order而不是普通with Order