Consider this snippet defining a trait for the state of a simulation, which a user is expected to implement in some derived type. On the trait, a collection of utility methods should be able to provide results that have the type of the implementation, similar to the way the Scala library collections do this. To achieve that, I think I need to parameterize the trait with the implementation type, like this:

trait State[+This <: State[This]] {
   def update : This  // result has type of State's implementor
}

Now I would like to define a multi-step update method, like this:

def update(steps: Int) : This 

When I try the naive approach:

def update(steps: Int) : This = 
    (this /: (0 until steps))( (s,n) => s.update )

the compiler complains about a type mismatch:

 error: type mismatch;
 found: State[This]
 required: This

which makes sense, since this, seen within State, has type State[This]. To get the code to compile, it seems I have to do an explicit cast:

def update(steps: Int) : This = 
    (this.asInstanceOf[This] /: (0 until steps))( (s,n) => s.update )

Is there a way to avoid this explicit cast, or more generally to achieve the intended result in a better way? Thanks.

有帮助吗?

解决方案

You need to add a self-type annotation to ensure that State is a This:

trait State[+This <: State[This]] { this: This =>
  def update: This  // result has type of State's implementor
}

A possible way to redefine the update(Int) method without a fold would be:

def update(steps: Int): This = Iterator.iterate(this)(_.update).drop(steps).next
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top