Я пытаюсь написать класс в scala, который оборачивает (параметризованную) коллекцию и переопределяет ее метод foreach. То, что он делает с методом foreach, не имеет значения для целей этого вопроса, поэтому предположим, что он просто печатает каждый элемент по мере его посещения. Поэтому в идеале мы можем использовать упаковщик следующим образом:
scala> val a = List(1,2,3,4,5)
scala> val b = MyWrapper(a)
scala> b.foreach{ x => x }
1
2
3
4
5
Ключ в том, что я хочу, чтобы это работало с любой итерацией; не просто список. Итак, моя первая попытка была похожа на следующее
class MyWrapper[A, S[A] <: Iterable[A]]( val s: S[A] with IterableLike[A, S[A]])
extends IterableLike[A, S[A]] {
override def foreach[U](f: A => U): Unit = {
iterator.foreach{ x => println(x); f(x) }
}
}
Однако, чтобы этот класс был конкретным, нам нужен метод итератора и метод newBuilder. Метод итератора не проблема, мы можем просто «украсть» итератор s следующим образом:
override def iterator = s.iterator
Проблема в том, когда я пытаюсь определить newBuilder. Мне нужен строитель, чтобы вернуть S [A]. Тем не менее, S [A] является параметризованной коллекцией, которая ограничена Iterable [A]. Таким образом, все мои попытки использования genericBuilder или получения компоновщика объекта-компаньона приводят к Iterable [A], а не к S [A], с соответствующими сообщениями об ошибках
[error] method newBuilder in trait TraversableLike of type => scala.collection.mutable.Builder[A,S[A]] is not defined
[error] method seq in trait Parallelizable of type => scala.collection.TraversableOnce[A] is not defined
Как получить построитель, который создает определенный тип , S [A], а не общий ограниченный тип Iterable [A]? Это вообще возможно? Будем весьма благодарны за любую помощь в понимании идиоматического способа Scala сделать это (или любого другого способа, который действительно работает)!