Skip to content

Instantly share code, notes, and snippets.

@ahoy-jon
Last active April 27, 2017 07:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ahoy-jon/1543c6bd7ce61dbfcc97 to your computer and use it in GitHub Desktop.
Save ahoy-jon/1543c6bd7ce61dbfcc97 to your computer and use it in GitHub Desktop.
Trying to transduce in Scala
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()))
}
package ahoy
object transducer {
type Reducer[A, R] = R => A => R
type Transducer[A, B] = (Reducer[A, R] => Reducer[B, R]) forSome {type R}
def map[A, B](f: A => B): Transducer[B, A] = {
def t[T]: Transducer[B, A] = {
xf: Reducer[B, T] => {
r: T => a: A => {
xf(r)(f(a))
}
}
}
t
}
def filter[A](pred: A => Boolean): Transducer[A, A] = {
def t[T]: Transducer[A,A] = {
xf: Reducer[A,T] => {
r:T => a:A => {
if(pred(a)) {
xf(r)(a)
} else {
r
}
}
}
}
t
}
def compose[A,B,C](t1:Transducer[A,B],t2:Transducer[C,A]):Transducer[C,B] = {
def t[T]:Transducer[C,A] = {
xf:Reducer[C,T] => {
t1(t2(xf))
}
}
t
}
}
object MyApp extends App {
import transducer._
val p: Int => Boolean = _ % 2 == 0
val inc:Int => Int = _ + 1
val m = transducer.map(inc)
val f = transducer.filter(p)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment