2014-05-22 2 views
2

스칼라 2.10.2에서 나는 내 자신의 간단한 컬렉션을 롤링하여 컬렉션 계층 구조에 대해 더 자세히 배우려고합니다.스칼라 컬렉션 CanBuildFrom

다음은 정수 시퀀스를 나타내는 장난감 클래스의 소스 코드입니다. 내가 가진

import scala.collection.SeqLike 
import scala.collection.mutable.Builder 
import scala.collection.generic.CanBuildFrom 

object IntSeq 
{ 
    def apply(ints : Int*) : IntSeq = new IntSeq(ints) 

    protected def newBuilder(iterable : Iterable[Int]) : Builder[Int,IntSeq] = new Builder[Int,IntSeq] 
    { 
     var init = scala.collection.mutable.ArrayBuffer(iterable.toSeq:_*) 
     def +=(elem : Int) : this.type = { init += elem; this } 
     def result() : IntSeq = new IntSeq(init) 
     def clear() : Unit = init = scala.collection.mutable.ArrayBuffer[Int]() 
    } 

    implicit def canBuildFrom : CanBuildFrom[Iterable[Int],Int,IntSeq] = new CanBuildFrom[Iterable[Int],Int,IntSeq] 
    { 
     def apply() : Builder[Int,IntSeq]= newBuilder(Seq()) 
     def apply(from : Iterable[Int]) : Builder[Int,IntSeq] = newBuilder(from) 
    } 
} 

class IntSeq(seq : Seq[Int]) 
    extends Seq[Int] 
    with SeqLike[Int,Seq[Int]] 
{ 
    def sumSquared() = seq.map(i => i * i).sum 

    // SeqLike interface 
    def iterator : Iterator[Int] = seq.iterator 

    def apply(idx : Int) : Int = seq(idx) 

    def length : Int = seq.length 
} 

문제는 다음과 다음 summary section of the page "The Architecture of Scala Collections"에, 점 4는 동반자 개체에 map을 암시 canBuildFrom을 제공함으로써와 유사한 기능이 클래스의 인스턴스를 반환합니다 말한다. 그러나 이는 발생하지 않습니다.

scala> IntSeq((1 to 10):_*).filter(_ % 2 == 0) 
res0: Seq[Int] = List(2, 4, 6, 8, 10) 

누구에게 이것이 어떤 이유인지 밝힐 수 있습니까?

답변

4

어떤 필터 방법이 반환하는지보세요. TraversableLike에서 Repr 유형을 반환합니다. SeqLike의 두 번째 유형 매개 변수와 동일한 유형입니다. 귀하의 경우에는 Seq [Int]입니다. 모든 것이 예상대로 작동합니다. IntSeq 형식을 얻으려면 :

class IntSeq(seq : Seq[Int]) 
    extends Seq[Int] 
    with SeqLike[Int,IntSeq] 
0

filter (SeqLike[A, Repr])은 많은 유사한 방법과 마찬가지로 Repr 유형의 값을 반환합니다. 그러나 수업을 SeqLike[Int, Seq[Int]]까지 연장했습니다. 클래스에 대한 연산이 IntSeq 유형의 값을 반환하도록하려면 SeqLike[Int, IntSeq]을 확장해야합니다.