覆盖Scala中更高级的抽象类型

时间:2012-01-11 15:18:48

标签: 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通用?

1 个答案:

答案 0 :(得分:1)

使用“-Ydependent-method-types”,

def Expr(_bo: BaseOps = PlusOp) = new BaseOps {
    override type T[A] = _bo.T[A]
    val bo: _bo.type = _bo
}

但是,我不知道这究竟意味着什么......