Следующего код показывает неглубокую иерархию, в которой тип, представляющий общую бинарную операцию используется для обоснования параметризованного абстрактного типа в другой мелкой иерархии контейнера:Переопределения выше-kinded абстрактных типов в Scala
trait BinaryOp[A] extends ((A,A) => A)
trait Plus[A] extends BinaryOp[A]
trait Minus[A] extends BinaryOp[A]
trait BaseOps {
type T[A] <: BinaryOp[A]
def apply[B](one: B, two: B)(op: T[B]) = op(one, two)
}
case object PlusOp extends BaseOps {
override type T[A] = Plus[A]
}
case object MinusOp extends BaseOps {
override type T[A] = Minus[A]
}
object App {
val plus = new Plus[Int] {
def apply(i: Int, i2: Int) = i + i2
}
def main(a: Array[String]) {
val exp = Expr(PlusOp)
exp.bo(1,2)(plus)
}
}
Идея заключается в том чтобы иметь возможность заявить операцию, которая может быть действительной для многих разных типов спереди, без привязки к операции типа. Если я определить класс выражений в общем, все хорошо
case class Expr[T <: BaseOps](bo: T = PlusOp)
Однако для моего случая использования нежелательно для Expr, чтобы быть paremeterized:
case class Expr(bo: BaseOps = PlusOp)
Следующий код не без родового Expr:
object App {
val plus = new Plus[Int] {
def apply(i: Int, i2: Int) = i + i2
}
def main(a: Array[String]) {
val exp = Expr(PlusOp)
exp.bo(1,2)(plus)
}
}
ошибка:
found : App.plus.type (with underlying type java.lang.Object with Plus[Int])
required: exp.bo.T[Int]
exp.bo(1,2)(plus)
Похоже, что информация типа от абстрактного типа T[A] <: BinaryOp[A]
не подтверждается информацией в подтипе PlusOp
, которая переопределяет абстрактный тип как T[A] = Plus[A]
. Есть ли способ обойти это без создания Expr
generic?