This all seems unnecessarily complicated if it’s okay if it’s not super fast, and unnecessarily slow if you want it fast.
In 2.12, the following is all you need to preserve collection types and be full speed:
import collection.generic.CanBuildFrom
def traverse[A, CC[A] <: collection.Iterable[A], E, B](xs: CC[A])(f: A => Either[E, B])(implicit cbf: CanBuildFrom[Nothing, B, CC[B]]): Either[E, CC[B]] = {
val builder = cbf()
val i = xs.iterator
while (i.hasNext) f(i.next) match {
case Right(b) => builder += b
case Left(e) => return Left(e)
}
Right(builder.result)
}
The types setting stuff up are complicated because of the CanBuildFrom stuff, but the inside is a simple loop.