Skip to content

Instantly share code, notes, and snippets.

@pvlugter
Created October 19, 2010 05:17
Show Gist options
  • Save pvlugter/633659 to your computer and use it in GitHub Desktop.
Save pvlugter/633659 to your computer and use it in GitHub Desktop.
package reactive
import scala.collection.SeqLike
import scala.collection.generic._
import scala.collection.mutable.{Builder, ListBuffer}
trait TransformedSeq[+A] extends Seq[A]
with GenericTraversableTemplate[A, TransformedSeq]
with SeqLike[A, TransformedSeq[A]] {
override def companion: GenericCompanion[TransformedSeq] = TransformedSeq
val underlying: Seq[A]
def apply(i: Int): A = underlying(i)
def length = underlying.length
def iterator = underlying.iterator
}
object TransformedSeq extends SeqFactory[TransformedSeq] {
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, TransformedSeq[A]] = new GenericCanBuildFrom[A]
def newBuilder[A]: Builder[A, TransformedSeq[A]] = new ListBuffer[A] mapResult fromSeq
def fromSeq[A](seq: Seq[A]) = new TransformedSeq[A] { val underlying = seq }
}
trait Signal[A] extends SignalLike[A, Signal[A]] {
def content: A
}
object Signal {
def apply[A](value: A) = new ValueSignal(value)
}
trait SignalLike[A, +This <: SignalLike[A, This]] {
def map[B, To](f: A => B)(implicit mapper: SignalMapper[This, A, B, To]): To
}
class ValueSignal[A](value: A) extends Signal[A] with SignalLike[A, ValueSignal[A]] {
def content = value
def map[B, To](f: A => B)(implicit mapper: SignalMapper[ValueSignal[A], A, B, To]): To = mapper(this, f)
override def toString = "ValueSignal(" + content + ")"
}
class SeqSignal[A](seq: TransformedSeq[A]) extends Signal[TransformedSeq[A]] with SignalLike[TransformedSeq[A], SeqSignal[A]] {
def this(seq: Seq[A]) = this(TransformedSeq(seq: _*))
def content = seq
def map[B, To](f: TransformedSeq[A] => B)(implicit mapper: SignalMapper[SeqSignal[A], TransformedSeq[A], B, To]): To = mapper(this, f)
override def toString = seq.mkString("SeqSignal(", ", ", ")")
}
object SeqSignal {
def apply[A](values: A*) = new SeqSignal(TransformedSeq(values: _*))
}
trait SignalMapper[-From, A, B, To] {
def apply(from: From, f: A => B): To
}
trait GenericSignalMapper {
implicit def mapSignal[A, B] = new SignalMapper[Signal[A], A, B, ValueSignal[B]] {
def apply(s: Signal[A], f: A => B): ValueSignal[B] = new ValueSignal(f(s.content))
}
}
object SignalMapper extends GenericSignalMapper {
implicit def mapSeqSignal[A, B] = new SignalMapper[SeqSignal[A], TransformedSeq[A], TransformedSeq[B], SeqSignal[B]] {
def apply(s: SeqSignal[A], f: TransformedSeq[A] => TransformedSeq[B]): SeqSignal[B] = new SeqSignal(f(s.content))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment