Last active
January 7, 2016 03:03
-
-
Save kaisellgren/11393718 to your computer and use it in GitHub Desktop.
Revisions
-
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // How do I implement foldp[A, B] for SignalImmutable[A] (or SignalSM[A]) ? // TODO: Does not work at all! def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, A) => B): SignalImmutable[B] = { -
kaisellgren revised this gist
Apr 29, 2014 . 3 changed files with 11 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,10 @@ // This first Signal[A] impl. uses STM (Ref — transactional references). class Signal[A](initial: A) { type SignalListener = Function[A, Unit] val value = Ref(initial) val listeners = Ref(Seq[SignalListener]()) def set(newValue: A): Unit = { // Atomically change the value within a transaction, blocks the thread, but a not an issue since it's a simple operation. @@ -20,7 +20,7 @@ class Signal[A](initial: A) { } /** Sets a new listener. */ def listen(listener: SignalListener): Unit = atomic { implicit txn => listeners() = listeners() :+ listener } } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,8 @@ // An immutable version called SignalImmutable[A]. Based on the concept of state transformations. package object Foo { type SignalListener = Function[A, Unit] } case class SignalImmutable[A](value: A, listeners: Seq[SignalListener] = Seq()) object SignalImmutable { def set[A](newValue: A)(signal: SignalImmutable[A]): SignalImmutable[A] = { @@ -10,7 +12,7 @@ object SignalImmutable { def get[A](signal: SignalImmutable[A]): A = signal.value def listen[A](listener: SignalListener)(signal: SignalImmutable[A]): SignalImmutable[A] = { signal.copy(listeners = signal.listeners :+ listener) } } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,8 @@ // This version is immutable and uses state monads. package object Foo { type SignalListener = Function[A, Unit] } case class SignalSM[A](value: A, listeners: Seq[SignalListener] = Seq()) object SignalSM { def set[A](newValue: A): State[SignalSM[A], Unit] = State(signal => { @@ -10,7 +12,7 @@ object SignalSM { def get[A]: State[SignalSM[A], A] = State(signal => (signal, signal.value)) def listen[A](listener: SignalListener): State[SignalSM[A], Unit] = State(signal => { (signal.copy(listeners = signal.listeners :+ listener), ()) }) } -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 9 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,27 +1,27 @@ // This version is immutable and uses state monads. case class SignalSM[A](value: A, listeners: Seq[Function[A, Unit]] = Seq()) object SignalSM { def set[A](newValue: A): State[SignalSM[A], Unit] = State(signal => { signal.listeners.foreach(_(newValue)) (signal.copy(value = newValue), ()) }) def get[A]: State[SignalSM[A], A] = State(signal => (signal, signal.value)) def listen[A](listener: Function[A, Unit]): State[SignalSM[A], Unit] = State(signal => { (signal.copy(listeners = signal.listeners :+ listener), ()) }) } object Foo extends App { val state = for { _ <- SignalSM.set(10) _ <- SignalSM.listen({ value: Int => println(s"Here it is: $value")}) _ <- SignalSM.set(20) s <- State.get } yield s state.exec(SignalSM(5)) } -
kaisellgren revised this gist
Apr 29, 2014 . 2 changed files with 28 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ // This version is immutable and uses state monads. case class SignalImmutableStateMonad[A](value: A, listeners: Seq[Function[A, Unit]] = Seq()) object SignalImmutableStateMonad { def set[A](newValue: A): State[SignalImmutableStateMonad[A], Unit] = State(signal => { signal.listeners.foreach(_(newValue)) (signal.copy(value = newValue), ()) }) def get[A]: State[SignalImmutableStateMonad[A], A] = State(signal => (signal, signal.value)) def listen[A](listener: Function[A, Unit]): State[SignalImmutableStateMonad[A], Unit] = State(signal => { (signal.copy(listeners = signal.listeners :+ listener), ()) }) } object Foo extends App { val state = for { _ <- SignalImmutableStateMonad.set(10) _ <- SignalImmutableStateMonad.listen({ value: Int => println(s"Here it is: $value")}) _ <- SignalImmutableStateMonad.set(20) s <- State.get } yield s state.exec(SignalImmutableStateMonad(5)) } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // How do I implement foldp[A, B] for SignalImmutable[A] (or SignalImmutableStateMonad[A]) ? // TODO: Does not work at all! def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, A) => B): SignalImmutable[B] = { -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,7 @@ def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, val result = SignalImmutable(initial) SignalImmutable.listen({ ev: A => // Great, so how do I actually update ´result´? SignalImmutable.set(predicate(SignalImmutable.get(result), ev)) })(source) @@ -15,6 +16,7 @@ object Foo extends App { val clicks = SignalImmutable(0) val totalClicks = foldpImmutable(clicks, 0) {(previous: Int, current: Int) => previous + 1} // This creates a new SignalImmutable, all hell breaks loose. SignalImmutable.set(0)(clicks) println(totalClicks.value) -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ // foldp[A, B] impl. for Signal[A], i.e. the STM -version. // This function is defined as: foldp := (Signal<A>, (B, A) => B, B) => Signal<B> def foldp[A, B](source: Signal[A], initial: B)(predicate: (B, A) => B): Signal[B] = { val result = new Signal(initial) -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // An immutable version called SignalImmutable[A]. Based on the concept of state transformations. case class SignalImmutable[A](value: A, listeners: Seq[Function[A, Unit]] = Seq()) -
kaisellgren revised this gist
Apr 29, 2014 . 4 changed files with 6 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // This first Signal[A] impl. uses STM (Ref — transactional references). class Signal[A](initial: A) { type Listener = Function[A, Unit] This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // An immutable version of Signal[A]. Based on the concept of state transformations. case class SignalImmutable[A](value: A, listeners: Seq[Function[A, Unit]] = Seq()) This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // foldp[A, B] impl. for Signal[A], i.e. the STM -version. // foldp := (Signal<A>, (B, A) => B, B) => Signal<B> def foldp[A, B](source: Signal[A], initial: B)(predicate: (B, A) => B): Signal[B] = { This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // How do I implement foldp[A, B] for ImmutableSignal[A] ? // TODO: Does not work at all! def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, A) => B): SignalImmutable[B] = { -
kaisellgren revised this gist
Apr 29, 2014 . 2 changed files with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ def foldp[A, B](source: Signal[A], initial: B)(predicate: (B, A) => B): Signal[B val result = new Signal(initial) source.listen({ ev: A => result.set(predicate(result.get, ev)) }) result This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, val result = SignalImmutable(initial) SignalImmutable.listen({ ev: A => SignalImmutable.set(predicate(SignalImmutable.get(result), ev)) })(source) result -
kaisellgren renamed this gist
Apr 29, 2014 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
kaisellgren revised this gist
Apr 29, 2014 . 4 changed files with 49 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,16 +1,12 @@ 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 within a transaction, blocks the thread, but a not an issue since it's a simple operation. // Finally return the current state/set of listeners and calls them. atomic { implicit txn => value() = newValue listeners() @@ -21,6 +17,7 @@ class Signal[A](initial: A) { value() } /** Sets a new listener. */ def listen(listener: Listener): Unit = atomic { implicit txn => listeners() = listeners() :+ listener } @@ -30,7 +27,7 @@ object Foo extends App { val slot = new Signal(0) slot.listen({ value => println(value) // Hooray! it prints 5! }) slot.set(5) This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // An immutable version of Signal[A]. case class SignalImmutable[A](value: A, listeners: Seq[Function[A, Unit]] = Seq()) object SignalImmutable { @@ -14,6 +16,7 @@ object SignalImmutable { } object Foo extends App { // New instances after every state change. Ugly, yes. val sig = SignalImmutable(1) val sig2 = SignalImmutable.listen({v: Int => println(v)})(sig) val sig3 = SignalImmutable.set(5)(sig2) This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,21 @@ // How do I implement this? // TODO: Does not work at all! def foldpImmutable[A, B](source: SignalImmutable[A], initial: B)(predicate: (B, A) => B): SignalImmutable[B] = { val result = SignalImmutable(initial) SignalImmutable.listen({ ev: A => SignalImmutable.set(predicate(SignalImmutable.get(result), source.value)) })(source) result } object Foo extends App { val clicks = SignalImmutable(0) val totalClicks = foldpImmutable(clicks, 0) {(previous: Int, current: Int) => previous + 1} SignalImmutable.set(0)(clicks) println(totalClicks.value) } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,21 @@ // foldp := (Signal<A>, (B, A) => B, B) => Signal<B> def foldp[A, B](source: Signal[A], initial: B)(predicate: (B, A) => B): Signal[B] = { val result = new Signal(initial) source.listen({ ev: A => result.set(predicate(result.get, source.get)) }) result } object Foo extends App { val clicks = new Signal(0) val totalClicks = foldp(clicks, 0) { (previous: Int, current: Int) => previous + 1} clicks.set(0) clicks.set(0) println(totalClicks.get) // 2! } -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,8 @@ // 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) -
kaisellgren revised this gist
Apr 29, 2014 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ 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) } -
kaisellgren created this gist
Apr 29, 2014 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,36 @@ // Haskell Signal foldp implementation. class Signal[A](initial: A) { // Listener :: A => Unit or however you annotate it in Haskell.. 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) }