如何使用 mixin 实现 F-bounded 多态性?
How to achieve F-bounded poly-morphism with a mixin?
假设我有一个 mixin 特征,我想在其中定义一个方法,其 return 类型取决于特征混合到的对象的最终类型...
trait MultiUnit extends Quantity {
this: Order =>
def split(unmatchedQuantity: Long): (???, ???)
}
...例如,如果我有一个案例 class 混合在 MultiUnit
中,我希望 return 类型看起来如下...
case class MultiUnitLimitOrder(price: Double, quantity: Long) extends Order with MultiUnit {
def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ???
}
...如果可能的话,我更喜欢使用类型成员而不是类型参数的解决方案。
如果 MultiUnit
的上限足够,您可以:
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) = ???
}
我不会像您上面建议的那样使用抽象类型成员,f bounded 是正确的方法。如果您事先不知道 T
的类型,则该类型成员模式很有用,例如,您正在计算一个类型。当您请求隐式证据时,Shapeless 一直使用该模式,例如:
def test[Computed]()(implicit gen: Generic.Aux[Source, Computed]): Result[Computed] = {}
这个用来"transfer"Generic
里面的一个内部类型成员的值class到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
.
假设我有一个 mixin 特征,我想在其中定义一个方法,其 return 类型取决于特征混合到的对象的最终类型...
trait MultiUnit extends Quantity {
this: Order =>
def split(unmatchedQuantity: Long): (???, ???)
}
...例如,如果我有一个案例 class 混合在 MultiUnit
中,我希望 return 类型看起来如下...
case class MultiUnitLimitOrder(price: Double, quantity: Long) extends Order with MultiUnit {
def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ???
}
...如果可能的话,我更喜欢使用类型成员而不是类型参数的解决方案。
如果 MultiUnit
的上限足够,您可以:
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) = ???
}
我不会像您上面建议的那样使用抽象类型成员,f bounded 是正确的方法。如果您事先不知道 T
的类型,则该类型成员模式很有用,例如,您正在计算一个类型。当您请求隐式证据时,Shapeless 一直使用该模式,例如:
def test[Computed]()(implicit gen: Generic.Aux[Source, Computed]): Result[Computed] = {}
这个用来"transfer"Generic
里面的一个内部类型成员的值class到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
.