Created
November 1, 2014 18:08
-
-
Save paulp/7c69c7ba268686402b97 to your computer and use it in GitHub Desktop.
Fixed transducers from http://blog.podsnap.com/ducers2.html
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
object TransducerUniversal { | |
type Reduct[-A, R] = (R, A) => R | |
trait Trans[+A, -B] { def apply[R](f: Reduct[A, R]): Reduct[B, R] } | |
def map[A, B](f: A => B): Trans[B, A] = new Trans[B, A] { def apply[R](rf: Reduct[B, R]) = (r, a) => rf(r, f(a)) } | |
def filter[A](p: A => Boolean): Trans[A, A] = new Trans[A, A] { def apply[R](rf: Reduct[A, R]) = (r, a) => if (p(a)) rf(r, a) else r } | |
def comp[A,B,C](t1 : Trans[A, B], t2 : Trans[C, A]): Trans[C, B] = new Trans[C, B] { def apply[R](rf: Reduct[C, R]) = t1(t2(rf)) } | |
def sequence[A, B](t: Trans[B, A], data: Seq[A]) = data.foldLeft(Seq[B]())(t(_ :+ _)) | |
implicit class Compable[A,B](t1: Trans[A, B]) { | |
def compose[C](t2: Trans[C, A]): Trans[C, B] = comp(t1, t2) | |
def ∘[C](t2: Trans[C, A]): Trans[C, B] = compose(t2) | |
def transform[R](rf: Reduct[A, R]) = t1(rf) | |
def ⟐[R] = transform[R] _ | |
} | |
def ⋅[A,B,C](t1: Trans[A, B], t2: Trans[C, A]): Trans[C, B] = comp(t1,t2) | |
def o[A,B,C](t1: Trans[A, B], t2: Trans[C, A]): Trans[C, B] = comp(t1,t2) | |
} | |
object Test { | |
import TransducerUniversal._ | |
def main(args: Array[String]): Unit = { | |
val t_parsei: Trans[Int, String] = map(_.toInt) | |
val t_root2 : Trans[Double, Int] = map(i => Math.pow(2.0, 1.0 / i)) | |
def t_repeat[A, R] = new Trans[A, A] { def apply[R](rf: Reduct[A, R]) = (r, a) => rf(rf(r, a), a) } | |
println(sequence(t_parsei ∘ t_repeat ∘ t_root2, List("1", "2", "3"))) | |
println(List("1", "2", "3").foldLeft(0.0d)(t_parsei ∘ t_repeat ∘ t_root2 ⟐ (_ + _))) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment