Skip to content

Instantly share code, notes, and snippets.

@paulp
Created November 1, 2014 18:08
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save paulp/7c69c7ba268686402b97 to your computer and use it in GitHub Desktop.
Save paulp/7c69c7ba268686402b97 to your computer and use it in GitHub Desktop.
Fixed transducers from http://blog.podsnap.com/ducers2.html
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