2010-12-11 4 views
0

具体的なタイプのセットを表すクラスで、不変のセットを拡張することに本当に苦労します。私は素晴らしいDSLを作成しようとしています。具体的なタイプのスカラセットを拡張する

私はクラスシングを持ちたいと思います。一緒に「もの」を追加すると、セットを拡張するThingSetオブジェクトが得られます。

class Thing(val name:String){ 
    def +(other: Thing):ThingSet = new ThingSet() + other 
} 

私はThingSetオブジェクトの作り方を理解できません。私はGenericSetTemplate、SetLikeなどのような特性を混在させる必要があることを知っていますが、私はそれを動作させることはできません。

教えてもらうために十分な明示的なものが見つからないので、誰かに教えてください。私はBitSetとHashSetの実装を見てみましたが、紛失してしまいます。

+0

まあ...あなたは 'ThingSet'に' this'を追加するのを忘れたので、あなたはそのバグを修正したいかもしれません。 :-) –

答えて

7

this Daily Scala投稿と同様にソースはBitSetになりました。この例はパラメータ化されたコレクションではなく、むしろ短く簡単です。

import scala.collection.SetLike 
import scala.collection.generic.{GenericSetTemplate, GenericCompanion, CanBuildFrom} 
import scala.collection.mutable.{Builder, SetBuilder} 

class ThingSet(seq : Thing*) extends Set[Thing] 
          with SetLike[Thing, ThingSet] 
          with Serializable { 
    override def empty: ThingSet = new ThingSet() 
    def + (elem: Thing) : ThingSet = if (seq contains elem) this 
     else new ThingSet(elem +: seq: _*) 
    def - (elem: Thing) : ThingSet = if (!(seq contains elem)) this 
     else new ThingSet(seq filterNot (elem ==): _*) 
    def contains (elem: Thing) : Boolean = seq exists (elem ==) 
    def iterator : Iterator[Thing] = seq.iterator 
} 

object ThingSet { 
    def empty: ThingSet = new ThingSet() 
    def newBuilder: Builder[Thing, ThingSet] = new SetBuilder[Thing, ThingSet](empty) 
    def apply(elems: Thing*): ThingSet = (empty /: elems) (_ + _) 
    def thingSetCanBuildFrom = new CanBuildFrom[ThingSet, Thing, ThingSet] { 
     def apply(from: ThingSet) = newBuilder 
     def apply() = newBuilder 
    } 
} 
3

Setのscaladocsからは、4つまたは5つのメソッドを実装する必要があると思います。このケースでは、実際のセット実装を作成するためにバックシングSeq [Thing]を使用することに決めました。

Set(I'm a new thing, I'm some other thing) 

注:中

class ThingSet(things: Seq[Thing]) extends Set[Thing] { 
    def contains(key: Thing) = { things.contains(key) } 
    def iterator: Iterator[Thing] = { things.iterator } 
    def +(elem: Thing) = new ThingSet(things :+ elem) 
    def -(elem: Thing) = new ThingSet(things.filterNot(_ == elem)) 
    override def empty = new ThingSet(Nil) 
} 

class Thing(val name: String) { 
    def +(other: Thing) = { new ThingSet(List(this,other)) } 
    override def toString = name 
} 

val thing = new Thing("I'm a new thing") 
println(thing + new Thing("I'm some other thing")) 

結果は、私はあなたのスクリプトファイルではなく、理由シングとThingSet間の循環的な依存関係のREPLでこれを実行するために持っていると思います。

+1

この 'ThingSet'は、操作の際に' ThingSet'を返しません。 –

+0

私が実装したSetメソッドは、最初の2つを除いて行います。あなたはどのような操作を参照していますか? – Collin

+0

'map'や' filter'のようなメソッド。 –

関連する問題