6

特性TraversableLike[+A, +Repr]は、一部のファンクションがReprを返しますが、他のファンクションはファンクションのタイプパラメータThatを返す一方、コレクションを作成することができます。 ,++などの機能がデフォルトでThatReprなどと推定される場合は、CustomCollection[A]を定義する方法はありますか?ここで mapがデフォルトでカスタムコレクションを返すカスタムスカラコレクションを作成しますか?

がうまくいけば、私は希望の内容を説明するコードスニペットです:私は CustomCollection(2, 3, 4)する最後の行をしたいと思います

case class CustomCollection[A](list: List[A]) extends TraversableLike[A, CustomCollection[A]] { 
    protected[this] def newBuilder = new CustomCollectionBuilder[A] 
    def foreach[U](f: (A) => U) {list foreach f} 
    def seq = list 
} 

class CustomCollectionBuilder[A] extends mutable.Builder[A, CustomCollection[A]] { 
    private val list = new mutable.ListBuffer[A]() 
    def += (elem: A): this.type = { 
    list += elem 
    this 
    } 
    def clear() {list.clear()} 
    def result(): CustomCollection[A] = CustomCollection(list.result()) 
} 

object CustomCollection extends App { 
    val customCollection = CustomCollection(List(1, 2, 3)) 
    println(customCollection filter {x => x == 1}) // CustomCollection(1) 
    println(customCollection map {x => x + 1}) // non-empty iterator 
} 

+0

私はちょうど3分後の背後にあることのためだけに1 OM-NOM-NOMにログイン。 「タイムリーな編集」とは思われません。親指のロゴ付きのボタン。 –

答えて

4

あなたは洗練されたCanBuildFromインスタンスを提供コンパニオンオブジェクトを設定する必要があります。

import collection.TraversableLike 
import collection.generic.{CanBuildFrom, GenericCompanion, GenericTraversableTemplate, 
    TraversableFactory} 
import collection.mutable.{Builder, ListBuffer} 

object CustomCollection extends TraversableFactory[CustomCollection] { 
    def newBuilder[A] = new CustomCollectionBuilder[A] 
    implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, CustomCollection[A]] = 
    new CanBuildFrom[Coll, A, CustomCollection[A]] { 
     def apply(): Builder[A, CustomCollection[A]] = new CustomCollectionBuilder() 
     def apply(from: Coll): Builder[A, CustomCollection[A]] = apply() 
    } 
} 
case class CustomCollection[A](list: List[A]) extends Traversable[A] 
with TraversableLike[A, CustomCollection[A]] 
with GenericTraversableTemplate[A, CustomCollection] { 
    override def companion: GenericCompanion[CustomCollection] = CustomCollection 
    def foreach[U](f: A => U) { list foreach f } 
    override def seq = list 
} 

class CustomCollectionBuilder[A] extends Builder[A, CustomCollection[A]] { 
    private val list = new ListBuffer[A]() 
    def += (elem: A): this.type = { 
    list += elem 
    this 
    } 
    def clear() {list.clear()} 
    def result(): CustomCollection[A] = CustomCollection(list.result()) 
} 

val customCollection = CustomCollection(List(1, 2, 3)) 
val f = customCollection filter {x => x == 1} // CustomCollection[Int] 
val m = customCollection map {x => x + 1}  // CustomCollection[Int] 
+0

すばらしい答え!私はcbfを使う必要があると感じましたが、最も一般的な方法を見つけることができませんでした。このようなコレクションAPIの詳細については、どこにいても読めますか?私。 'TraversableLike'を拡張するだけでなく、' GenericTraversableTemplate'を拡張する必要があることを私はどのように知っていますか? –

+0

@ dicarlo2 - 私は一般に、自分がやっていることに最も似ているクラスのソースコードを見て、それらが混在しているものをコピーします。私は、これが、どのような機能が提供されているかを正確に知ることができないそれぞれの特性(どのようにすべてのダイヤモンド型継承パターンを解決したいか)によって決まります。 –

+0

@RexKerr Heh、これは私が通常やっているのと同じことですが、私がコンピュータから離れなければならない前にTraversableFactoryまで質問を投稿した後も、ダイヤモンド型継承パターン。あまりにも悪いことに、より良い言及はなく、文書は、各形質の間の関係が常に明るいというわけではありません。 –

関連する問題