0

I am trying to apply a partial function to a generic collection while returning a specific collection instead of Traversable of the original type.

Here's what I've tried (among other things):

def filter[A, B, C <: Traversable[A],Y<:B, D <: Traversable[Y]](xs: Option[D] with TraversableLike[A,Option[D]])(pf:PartialFunction[A,B]): D = {
   xs.collect(pf)
}

def filter[A, B, C <: Traversable[A], D <: Traversable[B]](xs: D with TraversableLike[A,D])(pf:PartialFunction[A,B])(implicit ev: B =:= Option[Double]): D = {
   xs.collect(pf)
}

Any ideas why implicit ev: B =:= Option[Double] doesn't find the correct types?

I got inspiration from these posts:
Returning original collection type in generic method

How do I apply the enrich-my-library pattern to Scala collections?

Writing my own generic map functioni

Adrian
  • 5,603
  • 8
  • 53
  • 85

1 Answers1

1

You can do this:

import scala.collection.Iterable
import scala.collection.generic.CanBuildFrom

def collect[C[_], A, B](col: C[A])
                       (pf: PartialFunction[A, B])
                      (implicit ev: C[A] <:< Iterable[A],
                                cbf: CanBuildFrom[Nothing, B, C[B]]): C[B] =
  col.iterator.collect(pf).to[C]
  • @Adrian Yes you can, but **Trasversable** does not have `iterator`. Thus, the code will be mostly the same, but more inefficient _(specially if you chain multiple transformations)_ - Anyways, I doubt there is any collection type that is **Trasversable** but no **Iterable**. – Luis Miguel Mejía Suárez Aug 16 '19 at 19:01