Ich habe eine Klasse wie folgt definiert:Wie spezifiziert man einen Typparameter beim Aufruf einer Funktion, während der Compiler auf den anderen schließen kann?
implicit class TraversableLikeView[+A, +Repr, Raw](self: Raw)(implicit cast: Raw => TraversableLike[A,Repr]) {
def filterByType[B, That](implicit bf: CanBuildFrom[Repr, B, That]): That = {
val result = cast(self).flatMap{
case tt: B => Some(tt)
case _ => None
}(bf)
result
}
}
Wenn es auf TraversableLikeView("abc" :: "def" :: Nil)
Aufruf:
Ich mag Typen Parameter B
angegeben werden, und Typparameter That
automatisch aus vordefinierten implicits abgeleitet werden. So nenne ich die Funktion wie folgt aus:
TraversableLikeView("abc" :: "def" :: Nil).filterByType[String, _].foreach{...}
Allerdings gab der Compiler mir diesen Fehler:
Error:(38, 56) unbound wildcard type
....filterByType[String, _].foreach{...
^
Warum scala ist nicht in der Lage, diese Art Parameter ableiten? Was soll ich tun, um es zu beheben?
UPDATE: Das nächste, was ich bekommen kann, ist wie folgt aus:
implicit class TraversableLikeView[A, Repr, Raw <% TraversableLike[A, Repr]](self: Raw) {
def filterByType[B] = new FilterByType[B]
class FilterByType[B] {
def apply[That](implicit bf: CanBuildFrom[Repr, B, That]): That = {
val result = self.flatMap{
case tt: B => Some(tt)
case _ => None
}(bf)
result
}
}
}
test("1") {
val res: Seq[String] = Seq("abc", "def").filterByType[String].apply
println(res)
val res2: Array[String] = Array("abc", "def").filterByType[String].apply
println(res2)
val res3: Set[String] = Set("abc", "def").filterByType[String].apply
println(res3)
}
jedoch der Compiler auf der Suche nach den Beweisen (die nicht einmal erforderlich sein sollen) zum Scheitern verurteilt scheint:
Error:(38, 33) value filterByType is not a member of Array[com.tribbloids.spookystuff.pages.PageLike]
val unfetched = pageLikes.filterByType[Unfetched].head
^
Wenn ich die Ansichtsbegrenzung abbringe funktioniert es perfekt (natürlich außer Array [String]), aber ich bin etwas überrascht zu sehen, dass es eine solche Umgehung braucht, um eine einfache Sache in scala zu implementieren.
Ja ist es wichtig, gebunden zu verwenden Ansicht, sonst ist diese Funktion nicht auf zB funktionieren Array ("a", "b"). Außerdem ist dies keine perfekte Lösung, da die Kompilierungsarten von listResult & setResult immer noch Traversable sind [String] – tribbloid