Как достичь F-ограниченного полиморфизма с помощью миксина?
Предположим, что у меня есть черта mixin, где я хочу определить метод, возвращаемый тип которого зависит от конечного типа объекта, в который эта черта смешивается...
trait MultiUnit extends Quantity {
this: Order =>
def split(unmatchedQuantity: Long): (???, ???)
}
...например, если у меня есть класс case, который смешивается в MultiUnit
, я бы хотел, чтобы возвращаемый тип выглядел следующим образом...
case class MultiUnitLimitOrder(price: Double, quantity: Long) extends Order with MultiUnit {
def split(unmatchedQuantity: Long): (MultiUnitLimitOrder, MultiUnitLimitOrder) = ???
}
...Я бы предпочел решение, которое использует члены типа вместо параметров типа, если это возможно.
2 ответа:
Я бы не стал использовать абстрактный член типа, как вы предлагаете выше, f bounded-это правильный путь. Этот шаблон элементов типа полезен, если вы заранее не знаете тип
T
, например, вы вычисляете тип. Бесформенный использует этот шаблон все время, когда вы требуете неявных доказательств, таких как: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
.
Если верхняя граница на
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) = ??? }