Scala型投影

时间:2013-05-09 21:19:38

标签: scala

我有一组模型,每个模型都公开了一个下一个(...)方法,该方法通过一个离散步骤向前移动模型。每个next()方法都有一个由抽象类型T给出的参数。

我希望能够用另一个类包装每个模型,其中包装器也将继承类型T(每个模型不同),但提供额外的逻辑。通过让包装器也扩展模型,这将是微不足道的,但是对于我的实际模型实现的内部逻辑,这是不可行的。

我的解决方案是使用类似的预测:

trait Model {
  type T // works fine when this is a concrete implementation, but then cannot be overridden
  def next(input : T) = println(input)
}

abstract class Parent {
  type S <: Model
  type T = S#T
  val model : S
  def next(input : T) = model.next(input) 
}

这会因编译器错误而失败:类型不匹配; found:input.type(底层类型为Parent.this.T)必需:Parent.this.model.T

请注意,在Parent的任何具体实现中,Parent.this.T应该等于Parent.this.model.T。

到目前为止,我的解决方法是放弃使用类型系统,只为每个模型创建唯一的父类(即复制父可能公开的所有其他逻辑)。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

积分转到@senia。设置type T = model.T可以正常工作:

abstract class Parent {
  type S <: Model
  type T = model.T
  val model : S
  def next(input : T) = model.next(input) 
}

class SimpleParent[GT <: Model](val model: GT) extends Parent {
  type S = GT
}

trait StringModel extends Model { type T = String }
trait IntModel    extends Model { type T = Int }

object Test {
  new SimpleParent(new StringModel {})
  new SimpleParent(new IntModel {})
}

查看here,了解type T = S#T无效的原因。 (简短版本:我们可能model.type <: SS#T不具体,因此S#T可能与model.T不兼容。