Skip to content

Instantly share code, notes, and snippets.

@stepancheg
Created November 15, 2009 19:43
Show Gist options
  • Save stepancheg/235430 to your computer and use it in GitHub Desktop.
Save stepancheg/235430 to your computer and use it in GitHub Desktop.
ManagedSeq
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