Skip to content

Instantly share code, notes, and snippets.

@kaisellgren
Last active January 7, 2016 03:03
Show Gist options
  • Select an option

  • Save kaisellgren/11393718 to your computer and use it in GitHub Desktop.

Select an option

Save kaisellgren/11393718 to your computer and use it in GitHub Desktop.
Academic Scala implementations of Functional Reactive Programming -- different Signal[A] and foldp[A, B] implementations as examples
// Haskell Signal and foldp implementation.
// foldp := (Signal<A>, (B, A) => B, B) => Signal<B>
class Signal[A](initial: A) {
type Listener = Function[A, Unit]
val value = Ref(initial)
val listeners = Ref(Seq[Listener]())
def set(newValue: A): Unit = {
// Atomically change the value, blocks the thread, but a not an issue since it's a simple operation.
// Finally return the current state/set of listeners.
atomic { implicit txn =>
value() = newValue
listeners()
}.foreach(_(newValue))
}
def get: A = atomic { implicit txn =>
value()
}
def listen(listener: Listener): Unit = atomic { implicit txn =>
listeners() = listeners() :+ listener
}
}
object Foo extends App {
val slot = new Signal(0)
slot.listen({ value =>
println(value) // hooray!
})
slot.set(5)
}
case class SignalImmutable[A](value: A, listeners: Seq[Function[A, Unit]] = Seq())
object SignalImmutable {
def set[A](newValue: A)(signal: SignalImmutable[A]): SignalImmutable[A] = {
signal.listeners.foreach(_(newValue))
signal.copy(value = newValue)
}
def get[A](signal: SignalImmutable[A]): A = signal.value
def listen[A](listener: Function[A, Unit])(signal: SignalImmutable[A]): SignalImmutable[A] = {
signal.copy(listeners = signal.listeners :+ listener)
}
}
object Foo extends App {
val sig = SignalImmutable(1)
val sig2 = SignalImmutable.listen({v: Int => println(v)})(sig)
val sig3 = SignalImmutable.set(5)(sig2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment