I am having a tough time understanding why the Scala compiler is unhappy about this function definition:
def trimNonWordCharacters[T <: Iterable[String]](items: T): T =
items map { _.replaceAll("\\W", "") }
Here is the REPL output:
scala> def trimNonWordCharacters[T <: Iterable[String]](items: T): T =
items map { _.replaceAll("\\W", "") }
<console>:5: error: type mismatch;
found : Iterable[java.lang.String]
required: T
def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") }
The goal is to pass in any implementation of an Iterable and get the same type of back out. Is this possible?
The
mapmethod onIterablereturns anIterable, so even ifTis a subclass ofIterable, it’smapmethod will returnIterable.To get better typing, you’d have to write it like this:
However, that won’t work either, because there’s no information that let a map on
Tto generate anotherT. For example, mapping aBitSetinto aStringcannot result in aBitSet. So we need something else: something that teaches how to build aTfrom aT, where the mapped elements are of typeString. Like this: