Created
November 15, 2009 19:43
-
-
Save stepancheg/235430 to your computer and use it in GitHub Desktop.
ManagedSeq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection._ | |
import scala.collection.generic._ | |
import scala.collection.mutable.Builder | |
trait ManagedResource[+A] { self => | |
def acquireFor[R](f: A => R): R | |
def map[B](g: A => B): ManagedResource[B] = new ManagedResource[B] { | |
override def acquireFor[R](f: B => R) = { | |
self.acquireFor(x => f(g(x))) | |
} | |
} | |
} | |
trait ManagedIterator[+A] { self => | |
def managedIterator: ManagedResource[Iterator[A]] | |
def foreach[U](f: A => U): Unit = { | |
managedIterator.acquireFor { it => | |
it.foreach(f) | |
} | |
} | |
def mapIterator[B](f: Iterator[A] => Iterator[B]) = new ManagedIterator[B] { | |
override def managedIterator = self.managedIterator.map(f) | |
} | |
def slice(from: Int, to: Int) = mapIterator(_.slice(from, to)) | |
def map[B](f: A => B) = mapIterator(_.map(f)) | |
def filter(f: A => Boolean) = mapIterator(_.filter(f)) | |
def takeWhile(f: A => Boolean) = mapIterator(_.takeWhile(f)) | |
def dropWhile(f: A => Boolean) = mapIterator(_.dropWhile(f)) | |
} | |
trait ManagedSeqLike[+E, +Coll, +This <: ManagedSeq[E, Coll] with ManagedSeqLike[E, Coll, This]] | |
extends AnyRef | |
with TraversableView[E, Coll] | |
with TraversableViewLike[E, Coll, This] | |
{ self => | |
override def underlying: Coll = throw new Exception("no underlying") | |
def managedIterator: ManagedIterator[E] | |
override def foreach[U](f: E => U): Unit = | |
managedIterator.foreach(f) | |
trait Transformed[+F] extends ManagedSeq[F, Coll] with super.Transformed[F] { | |
override lazy val underlying: Coll = throw new Exception("no underlying") | |
} | |
trait Sliced extends Transformed[E] with super.Sliced { | |
override def managedIterator = self.managedIterator slice (from, until) | |
} | |
trait Mapped[F] extends Transformed[F] with super.Mapped[F] { | |
override def managedIterator = self.managedIterator map mapping | |
} | |
trait Filtered extends Transformed[E] with super.Filtered { | |
override def managedIterator = self.managedIterator filter pred | |
} | |
/* | |
trait FlatMapped[F] extends Transformed[F] with super.FlatMapped[F] { | |
override def managedIterator = self.managedIterator flatMap (mapping(_).toIterable.iterator) | |
} | |
trait Appended[F >: E] extends Transformed[F] with super.Appended[F] { | |
override def iterator = self.iterator ++ rest.toIterable.iterator | |
} | |
*/ | |
trait TakenWhile extends Transformed[E] with super.TakenWhile { | |
override def managedIterator = self.managedIterator takeWhile pred | |
} | |
trait DroppedWhile extends Transformed[E] with super.DroppedWhile { | |
override def managedIterator = self.managedIterator dropWhile pred | |
} | |
/* | |
trait Zipped[F] extends Transformed[(E, F)] { | |
protected[this] val other: Iterable[F] | |
override def iterator: Iterator[(E, F)] = self.iterator zip other.iterator | |
override def stringPrefix = self.stringPrefix+"Z" | |
} | |
trait ZippedAll[A1 >: E, F] extends Transformed[(A1, F)] { | |
protected[this] val other: Iterable[F] | |
protected[this] val thisElem: A1 | |
protected[this] val thatElem: F | |
override def iterator: Iterator[(A1, F)] = | |
self.iterator.zipAll(other.iterator, thisElem, thatElem) | |
} | |
override def zip[A1 >: E, F, That](that: Iterable[F])(implicit bf: CanBuildFrom[This, (A1, F), That]): That = { | |
newZipped(that).asInstanceOf[That] | |
// was: val b = bf(repr) | |
// if (b.isInstanceOf[NoBuilder[_]]) newZipped(that).asInstanceOf[That] | |
// else super.zip[A1, F, That](that)(bf) | |
} | |
override def zipWithIndex[A1 >: E, That](implicit bf: CanBuildFrom[This, (A1, Int), That]): That = | |
zip[A1, Int, That](Stream from 0)(bf) | |
override def zipAll[F, A1 >: E, That](that: Iterable[F], thisElem: A1, thatElem: F)(implicit bf: CanBuildFrom[This, (A1, F), That]): That = | |
newZippedAll(that, thisElem, thatElem).asInstanceOf[That] | |
protected def newZipped[F](that: Iterable[F]): Transformed[(E, F)] = new Zipped[F] { | |
val other = that | |
} | |
protected def newZippedAll[A1 >: E, F](that: Iterable[F], _thisElem: A1, _thatElem: F): Transformed[(A1, F)] = new ZippedAll[A1, F] { | |
val other: Iterable[F] = that | |
val thisElem = _thisElem | |
val thatElem = _thatElem | |
} | |
*/ | |
/** Boilerplate method, to override in each subclass | |
* This method could be eliminated if Scala had virtual classes | |
*/ | |
//protected override def newAppended[F >: E](that: Traversable[F]): Transformed[F] = new Appended[F] { val rest = that } | |
protected override def newMapped[F](f: E => F): Transformed[F] = new Mapped[F] { val mapping = f } | |
//protected override def newFlatMapped[F](f: E => Traversable[F]): Transformed[F] = new FlatMapped[F] { val mapping = f } | |
protected override def newFiltered(p: E => Boolean): Transformed[E] = new Filtered { val pred = p } | |
protected override def newSliced(_from: Int, _until: Int): Transformed[E] = new Sliced { val from = _from; val until = _until } | |
protected override def newDroppedWhile(p: E => Boolean): Transformed[E] = new DroppedWhile { val pred = p } | |
protected override def newTakenWhile(p: E => Boolean): Transformed[E] = new TakenWhile { val pred = p } | |
} | |
trait ManagedSeq[+A, +Coll] extends ManagedSeqLike[A, Coll, ManagedSeq[A, Coll]] | |
object ManagedSeq { | |
class NoBuilder[A] extends Builder[A, Nothing] { | |
def +=(elem: A): this.type = this | |
//def iterator: Iterator[A] = Iterator.empty | |
def iterator: Iterator[A] = throw new Exception("???") | |
@deprecated("use `iterator' instead") def elements = iterator | |
def result() = throw new UnsupportedOperationException("Builder.result") | |
def clear() {} | |
} | |
type Coll = ManagedSeq[_, C] forSome {type C <: ManagedSeq[_, _]} | |
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ManagedSeq[A, ManagedSeq[_, _]]] = | |
new CanBuildFrom[Coll, A, ManagedSeq[A, ManagedSeq[_, _]]] { | |
def apply(from: Coll) = new NoBuilder | |
def apply() = new NoBuilder | |
} | |
} | |
class Lines extends ManagedSeq[String, Lines] { | |
override def managedIterator: ManagedIterator[String] = new ManagedIterator[String] { | |
override def managedIterator = new ManagedResource[Iterator[String]] { | |
override def acquireFor[R](f: Iterator[String] => R) = { | |
val r = f(List("a", "b", "c").iterator) | |
println("done iteration") | |
r | |
} | |
} | |
} | |
} | |
val l = new Lines | |
val m0: ManagedSeq[String, _] = l.filter(_ != "b") | |
//val m: ManagedSeq[String, _] = m0.map(_ + "!") | |
val m: ManagedSeq[String, _] = m0 | |
println("constructed m") | |
m.foreach(println _) | |
for (it <- m.managedIterator) { | |
it.foreach(println _) | |
} | |
println("$") | |
// vim: set ts=4 sw=4 et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment