Funktion, die generisch einen Typ annimmt und denselben Typ zurückgibt

Es fällt mir schwer zu verstehen, warum der Scala-Compiler mit dieser Funktionsdefinition nicht zufrieden ist:

<code>def trimNonWordCharacters[T <: Iterable[String]](items: T): T =
     items map { _.replaceAll("\\W", "") }
</code>

Hier ist derREPL Ausgabe:

<code>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", "") }
</code>

Das Ziel ist es, bei jeder Implementierung eines Iterable die gleiche Art von Back-Out zu erzielen. Ist das möglich?

 Luigi Plinge05. Apr. 2012, 00:24
 Daniel C. Sobral05. Apr. 2012, 14:32
@LuigiPlinge Diese Frage brauchte ich nichtCanBuildFrom, schon seitfilter benötigt es nicht. Diese Frage ist sehr ähnlich, und dieTitel Von dieser Frage ist es sicherlich die Rede, aber hier ist ein bisschen mehr erforderlich, damit es funktioniert.

Antworten auf die Frage(2)

[Eingabe als Antwort statt als Kommentar, da der Code in Kommentaren nicht richtig formatiert ist]

@ Daniel, danke für die Erklärung, ich fand es auch nützlich. Da Iterable von IterableLike abgeleitet ist, scheint auch Folgendes zu funktionieren und ist etwas kompakter:

<code>import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
def trimNonWordCharacters[T <: IterableLike[String, T]]
 (items: T)
 (implicit cbf: CanBuildFrom[T, String, T]): T =
 items map { _.replaceAll("\\W", "") }
</code>
Lösung für das Problem

map Methode aufIterable gibt ein zurückIterablealso auch wennT ist eine Unterklasse vonIterable, es istmap Methode wird zurückkehrenIterable.

Um besser tippen zu können, müsstest du es so schreiben:

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

Dies wird jedoch auch nicht funktionieren, da es keine Informationen gibt, die eine Karte anzeigen lassenT ein anderes generierenT. Beispiel: Zuordnung aBitSet in einString kann nicht zu einem führenBitSet. Wir brauchen also etwas anderes: etwas, das lehrt, wie man eineT von einemT, wobei die zugeordneten Elemente vom Typ sindString. So was:

<code>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", "") }
</code>
 Jay Taylor05. Apr. 2012, 00:04
Vielen Dank. Ihre Erklärung ist sehr informativ und jetzt weiß ich endlich, wie ich sie verwenden kannCanBuildFrom (!)

Ihre Antwort auf die Frage