package ahoy import scala.collection.mutable object transducer { type Reducer[A, R] = R => A => R trait Transducer[A, B] { type T[R] = Reducer[A, R] => Reducer[B, R] def r[R]: T[R] def comp[C](t2: Transducer[C, A]): Transducer[C, B] = { val up = this new Transducer[C, B] { override def r[R]: (Reducer[C, R]) => Reducer[B, R] = { xf => up.r[R](t2.r(xf)) } } } def filter(pred:A => Boolean):Transducer[A,B] = this.comp(transducer.filter(pred)) def map[C](f:A=> C): Transducer[C, B] = this.comp(transducer.map(f)) } def map[A, B](f: A => B): Transducer[B, A] = new Transducer[B, A] { override def r[R]: (Reducer[B, R]) => Reducer[A, R] = { xf => r => a => xf(r)(f(a)) } } def filter[A](pred: A => Boolean): Transducer[A, A] = new Transducer[A, A] { override def r[R]: (Reducer[A, R]) => Reducer[A, R] = { xf => r => a => if (pred(a)) xf(r)(a) else r } } def it[A] = new Transducer[A, A] { override def r[R]: T[R] = xf => xf } def sequence[A, B](xf: Transducer[B, A], data: List[A]): List[B] = { val list: mutable.MutableList[B] = new mutable.MutableList[B]() val r1: (A) => Unit = xf.r[Unit](_ => b => { list.+=:(b) }).apply(null) data.foreach(r1) list.toList } } object MyApp extends App { def time[A](a: => A) = { for(i <- 0 to 10) { val now = System.nanoTime val result = a val micros = (System.nanoTime - now) / 1000 println("%d microseconds".format(micros)) } } import ahoy.transducer._ private val list: List[Int] = (1 to 5000000).toList time(sequence(it[Int].filter(_ % 2 == 0).map(_ + 3).map(_.toString()), list)) println("next") time(list.filter(_ % 2 == 0).map(_ + 3).map(_.toString())) }