2009-08-13 5 views
3

Ich habe mit einem unveränderlichen Objekt in scala 2.7.5 zu tun, und eines seiner Mitglieder ist ein immutable Sortedset. ich kein Problem mit dem Zusatz haben, zu synthetisieren, es gibt:Scala unveränderlich SortedSet sind nicht "stabil" beim Löschen

class MyClass[A](s:SortedSet[A]) { 
    ... 
    def + (elem:A):MyClass[A] { 
    new MyClass(s + elem) 
    } 
} 

Und es funktioniert, da + Betreiber Überlastung Merkmal SortedSet ist ein SortedSet zurückzukehren.

Leider ein Element zu entfernen nicht da - methos nicht überlastet ist:

class MyClass[A](s:SortedSet[A]) { 
    ... 
    def - (elem:A):MyClass[A] { 
    new MyClass(s - elem) // Compiler error: (s - elem) is a Set[A] 
    } 
} 

Hat jemand weiß, wie ich einen sortierte Satz erhalten kann, wenn ich ein Element unterdrücken zu wissen, dass: - ich will nicht verwenden, eine spezifischere Art von Set wie TreeSet. - Ich kann ein weniger spezifisches Merkmal als Set [A] anstelle meines SortedSet verwenden.

+0

Wie ich die SortedMap API überprüft habe und ... es tut es richtig ("-" gibt eine SortedMap zurück). Es muss eine Erklärung geben, Bonusfrage? – Nicolas

+0

Die Sammlungsbibliothek von Scala 2.7.x ist ad-hoc. Es wuchs mit der Zeit und dem Gebrauch, bis es so wurde, wie es ist. Das Entfernen dieser Art von Inkonsistenz ist ein Ziel hinter der neuen Sammlungsbibliothek von Scala 2.8. –

Antwort

3

Wenn Sie bis 2.8 warten können, sieht es so aus, dass dies ordnungsgemäß funktioniert.

Von SortedSetLike.scala (der Super-Eigenschaft des unveränderlichen SortedSet trait)

trait SortedSetLike[A, +This <: SortedSet[A] with SortedSetLike[A, This]] extends Sorted[A, This] with SetLike[A, This] 

Dies macht den This Typ ein SortedSet. Dann in SetLike.scala, die Unterschrift des - Operator ist

def - (elem: A): This 

So richtig ein SortedSet zurückkehren wird, wenn auf einem SortedSet verwendet.

+0

Ja, die Dinge sind besser in 2.8. Aber leider brauche ich einen Workaround für den 2.7.5. Danke trotzdem. – Nicolas

+0

Dargestellt, das war wahrscheinlich der Fall, aber dachte, es könnte sowieso nützlich sein –

0

Ich denke, alles, was Sie tun müssen, ist es zu werfen. "-" gibt ein Set zurück, aber es ist auch ein SortedSet. Es kann nicht schön sein, aber es funktioniert:

class MyClass[A](s:SortedSet[A]) { 
    def +(elem:A): MyClass[A] = { 
     new MyClass(s + elem) 
    } 

    def -(elem:A): MyClass[A] = { 
     new MyClass((s - elem).asInstanceOf[SortedSet[A]]) 
    } 

    override def toString = "sorted set = " + s 
    } 

    val a = new MyClass(new TreeSet[Int]) 
    println(a) // prints "sorted set = Set()" 
    val b = a + 1 
    println(b) // prints "sorted set = Set(1)" 
    val c = a - 1 
    println(c) // prints "sorted set = Set()" 
+0

Ich mache es, da die meisten der SortedSet muss ein SortedSet nach einem "-" zurückgeben. Aber das ClassCastException-Risiko, das mit dieser Lösung einhergeht, gefällt mir nicht. – Nicolas

1

Im Gegensatz zu dem, was man denken kann, - nicht garantieren SortedSet Ergebnis. Kleine Sets werden durch verschiedene Klassen optimiert. Da Set - abstrakt ist, wissen Sie nicht, wie es implementiert werden könnte, und eine ist frei, es in einer Weise zu implementieren, die eine nicht sortierte Menge zurückgibt.

Folgendes ist ineffizient, aber es funktioniert. Sie können es verwenden, leben mit asInstanceOf, oder warten Sie auf 2.8. :-)

class MyClass[A](s: SortedSet[A]) { 
    def -(elem: A)(implicit view: A => Ordered[A]): MyClass[A] = { 
    new MyClass(TreeSet(s.toList - elem: _*)) 
    } 
} 
+0

Warum haben Sie die Methode implizit anstelle der Klasse verwendet? Wenn ich es gut verstehe, kann sich der implizite Parameter von einem Anruf zu einem anderen ändern, und es erscheint mir peinlich, habe ich etwas übersehen? Und ja: Risiko eines Cast-Fehlers, warten oder eine ineffiziente Methode verwenden scheint die einzige Alternative zu sein. Ich denke, ich muss damit leben. – Nicolas

+0

Kein besonderer Grund für die implizite Methode.Ich habe gerade versucht, die MyClass-Deklaration beizubehalten, während du sie geschrieben hast. –