Scala: избегать приведения к типу параметра в foldLeft - PullRequest
2 голосов
/ 05 декабря 2011

Рассмотрим этот фрагмент, определяющий черту для состояния симуляции, которую пользователь должен реализовать в некотором производном типе. На этом признаке коллекция утилитарных методов должна быть в состоянии предоставить результаты, имеющие тип реализации, аналогично тому, как это делают коллекции библиотеки Scala. Для этого, я думаю, мне нужно параметризовать черту с помощью типа реализации, например:

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

Теперь я хотел бы определить метод многоэтапного обновления, например:

def update(steps: Int) : This 

Когда я пытаюсь наивный подход:

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

компилятор жалуется на несоответствие типов:

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

имеет смысл, поскольку this, видимый внутри State, имеет тип State [This]. Чтобы получить код для компиляции, кажется, мне нужно выполнить явное приведение:

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

Есть ли способ избежать этого явного приведения или, в более общем смысле, достичь желаемого результата лучшим способом? Благодарю.

1 Ответ

5 голосов
/ 05 декабря 2011

Необходимо добавить аннотацию самостоятельного типа, чтобы убедиться, что State является This:

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

Возможный способ переопределить метод update(Int) без сгиба:1007 *

def update(steps: Int): This = Iterator.iterate(this)(_.update).drop(steps).next
...