Function which generically takes a type and returns the same type

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?

Answers


The map method on Iterable returns an Iterable, so even if T is a subclass of Iterable, it's map method will return Iterable.

To get better typing, you'd have to write it like this:

import scala.collection.IterableLike
def trimNonWordCharacters[T <: Iterable[String]](items: T with IterableLike[String, T]): T =
     items map { _.replaceAll("\\W", "") }

However, that won't work either, because there's no information that let a map on T to generate another T. For example, mapping a BitSet into a String cannot result in a BitSet. So we need something else: something that teaches how to build a T from a T, where the mapped elements are of type String. Like this:

import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
def trimNonWordCharacters[T <: Iterable[String]]
                         (items: T with IterableLike[String, T])
                         (implicit cbf: CanBuildFrom[T, String, T]): T =
     items map { _.replaceAll("\\W", "") }

Need Your Help

Simple program to call R from Java using Eclipse and Rserve

java eclipse r rserve

My application must perform R operations such as:

How to convert string to uniqueidentifier?

c# string uniqueidentifier

I want to insert a string into a table as a uniqueidentifier type. But when I insert it to the database, it throws an error. How can i convert a string to a uniqueidentifier?