Concrete builder for parameterized type

I am trying to write a class in scala that wraps a (parameterized) collection and overrides its foreach method. What he does with the foreach method does not matter for the purpose of this question, therefore, it can be said that he simply prints each element during his visit. Therefore, ideally, we could use a wrapper as follows:

scala> val a = List(1,2,3,4,5) scala> val b = MyWrapper(a) scala> b.foreach{ x => x } 1 2 3 4 5 

The key is that I want this to work with any iterable; not just a list. So my first attempt was something like what follows

 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) } } } 

However, in order for this class to be concrete, we need an iterator method and a newBuilder method. The iterator method is not a problem, we can just β€œsteal” the iterator like this:

 override def iterator = s.iterator 

The problem is that I am trying to define newBuilder. I need a builder to get S [A] back. However, S [A] is a parameterized set that is limited to Iterable [A]. Thus, all my attempts to use genericBuilder or to get a compiler of companion objects result in Iterable [A], not S [A], with corresponding error messages

 [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 

How can I get a builder that builds a specific type S [A], and not a generic bounded type Iterable [A]? Is it possible? Any help in understanding the idiomatic scala method for this (or any method that really works) would be greatly appreciated!

+4
generics types scala builder parameterized
Jan 31 '12 at 18:13
source share
1 answer

IterableLike (and other XxxLike attributes) abstract by return type, delegating Builder, which must be specific to each type of collection. Therefore, what you are trying cannot work.

You can create a common wrapper MyWrapperLike [A, B] and a couple of specific wrappers MySeqWrapper [A] extends MyWrapperLike [A, Seq [A]] (the same for Set, Map, List, etc.), that is, imitate the design Scala collection libraries.

+2
Jan 31 '12 at 19:03
source share



All Articles