-
-
Save fkowal/f4ec3d6994b6132a47d746435febfb99 to your computer and use it in GitHub Desktop.
Trying to transduce in Scala
This file contains 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
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())) | |
} |
This file contains 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
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