Skip to content

Instantly share code, notes, and snippets.

@non
Created October 30, 2014 00:39
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save non/c07629bb938b0b4ba67b to your computer and use it in GitHub Desktop.
Save non/c07629bb938b0b4ba67b to your computer and use it in GitHub Desktop.
Slightly simpler example of typed transducers in Scala. See http://blog.podsnap.com/ducers2.html for more context.
object Transducer {
type RF[R, A] = (R, A) => R
def apply[A, B](f: A => B) =
new Transducer[B, A] {
def apply[R](rf: RF[R, B]) = (r, a) => rf(r, f(a))
}
}
import Transducer.RF
trait Transducer[A, B] { self =>
def apply[R](f: RF[R, A]): RF[R, B]
def ∘[Z](that: Transducer[Z, A]) =
new Transducer[Z, B] {
def apply[R](rf: RF[R, Z]) = self(that(rf))
}
}
object Test {
val parseI = Transducer((s: String) => s.toInt)
val root2 = Transducer((n: Int) => math.pow(2.0, 1.0 / n))
def repeat[A] =
new Transducer[A, A] {
def apply[R](rf: RF[R, A]) = (r, a) => rf(rf(r, a), a)
}
def main(args: Array[String]) {
val lst = List("1","2","3")
println(lst.foldLeft(0)(parseI(_ + _)))
println(lst.foldLeft(0.0)((parseI ∘ repeat ∘ root2)(_ + _)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment