Ich versuche, einige Erweiterungsmethoden für die Scala-Sammlungen zu schreiben, und stoße in Schwierigkeiten, sie vollständig zu erstellen.
Ein erster Versuch von tailOption ergibt etwas wie:
%Vor%Leider funktioniert das nicht:
%Vor%Scala 2.10 bietet die Klasse IsTraversableLike, um diese Art von Dingen für alle Sammlungen anzupassen (einschließlich der ungeraden, wie Strings).
Damit kann ich zum Beispiel tailOption ganz einfach implementieren:
%Vor% Das Ergebnis hat den korrekten Typ: Option[<input-type>]
. Insbesondere konnte ich den Repr
-Typ beibehalten, wenn Methoden aufgerufen werden, die Repr
zurückgeben, wie 'tail.
Leider kann ich diesen Trick nicht verwenden, um den Typ der Elemente der Sammlung zu erhalten. Ich kann Methoden, die ein Element zurückgeben, nicht aufrufen.
IsTraversableLike
hat ein Mitglied A, aber es scheint nicht sehr nützlich zu sein. Insbesondere kann ich meinen ursprünglichen Elementtyp nicht rekonstruieren und das Element ist nicht gleichwertig. Zum Beispiel, ohne weitere Arbeit, sieht headTailOption
wie folgt aus:
Wie wir sehen können, hat c einen wunderbar barocken Typ. Aber dieser Typ ist nicht äquivalent zu Char:
%Vor% Ich habe alle möglichen Tricks ausprobiert, einschließlich Repr[A] <: GenTraversableLike[A, Repr[A]]
, von denen keiner hilft. Kann jemand die magische Soße ausarbeiten, um headTailOption
die richtigen Typen für:
Eine Teilantwort. Sie haben wahrscheinlich mit dem Scaladoc-Beispiel für IsTraversableLike
begonnen. Es verwendet immer noch den "alten Ansatz", implizite Konvertierung zu trennen und die Wrapper-Klasse zu instanziieren, anstatt in einem Schritt durch eine implizite Klasse zu gehen. Es stellt sich heraus, dass der "alte Ansatz" funktioniert:
Wie Miles hervorhebt, scheint die Aufteilung dafür wesentlich zu sein, um mit der impliziten Suche und Typinferenz zu arbeiten.
Eine andere, wenn auch weniger elegante Lösung besteht darin, die Vereinheitlichung von Strings und Sammlungen aufzugeben:
%Vor% Sie können es als implizite Klasse schreiben, wenn Sie den Typ A
aus dem IsTraversableLike
extrahieren.
Oder äquivalent:
%Vor%Und dann funktioniert alles gut.
%Vor% Der Compiler weiß, dass scala.collection.generic.IsTraversableLike.stringRepr.A
dasselbe ist wie Char
.
Tags und Links scala