From 64106c4d3d4ddba8c7bc2af75376e6d3d3d75601 Mon Sep 17 00:00:00 2001 From: Date: Mon, 29 Jun 2015 20:16:15 +0000 Subject: Update documentation --- carboxyl/struct.Signal.html | 245 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 carboxyl/struct.Signal.html (limited to 'carboxyl/struct.Signal.html') diff --git a/carboxyl/struct.Signal.html b/carboxyl/struct.Signal.html new file mode 100644 index 0000000..16abc52 --- /dev/null +++ b/carboxyl/struct.Signal.html @@ -0,0 +1,245 @@ + + + + + + + + + + carboxyl::Signal - Rust + + + + + + + + + + + + + + + +
+

Struct carboxyl::Signal + + [] + + [src]

+
pub struct Signal<A> {
+    // some fields omitted
+}

A continuous signal that changes over time.

+ +

Signals can be thought of as values that change over time. They have both a +continuous and a discrete component. This means that their current value is +defined by a function that can be called at any time. That function is only +evaluated on-demand, when the signal's current value is sampled. (This is +also called pull semantics in the literature on FRP.)

+ +

In addition, the current function used to sample a signal may change +discretely in reaction to some event. For instance, it is possible to create +a signal from an event stream, by holding the last event occurence as the +current value of the stream.

+ +

Algebraic laws

+

Signals come with some primitive methods to compose them with each other and +with streams. Some of these primitives give the signals an algebraic +structure.

+ +

Functor

+

Signals form a functor under unary lifting. Thus, the following laws hold:

+ + + +

Applicative functor

+

By extension, using the notion of a signal of a function, signals also +become an applicative using Signal::new as pure and +|sf, sa| lift!(|f, a| f(a), &sf, &sa) as <*>.

+ +

TODO: Expand on this and replace the Haskell reference.

+

Methods

impl<A: Clone + 'static> Signal<A>

fn new(a: A) -> Signal<A>

+

Create a constant signal.

+

fn sample(&self) -> A

+

Sample the current value of the signal.

+

impl<A: Clone + Send + Sync + 'static> Signal<A>

fn cyclic<F>(def: F) -> Signal<A> where F: FnOnce(&Signal<A>) -> Signal<A>

+

Create a signal with a cyclic definition.

+ +

The closure gets an undefined forward-declaration of a signal. It is +supposed to return a self-referential definition of the same signal.

+ +

Sampling the forward-declared signal, before it is properly defined, +will cause a run-time panic.

+ +

This pattern is useful to implement accumulators, counters and other +loops that depend on the sampling behaviour of a signal before a +transaction.

+

fn snapshot<B, C, F>(&self, stream: &Stream<B>, f: F) -> Stream<C> where B: Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, F: Fn(A, B) -> C + Send + Sync + 'static

+

Combine the signal with a stream in a snapshot.

+ +

snapshot creates a new stream given a signal and a stream. Whenever +the input stream fires an event, the output stream fires an event +created from the signal's current value and that event using the +supplied function.

+
+let sink1: Sink<i32> = Sink::new();
+let sink2: Sink<f64> = Sink::new();
+let mut events = sink1.stream().hold(1)
+    .snapshot(&sink2.stream(), |a, b| (a, b))
+    .events();
+
+// Updating its signal does not cause the snapshot to fire
+sink1.send(4);
+
+// However sending an event down the stream does
+sink2.send(3.0);
+assert_eq!(events.next(), Some((4, 3.0)));
+
+

impl<A: Clone + Send + Sync + 'static> Signal<Signal<A>>

fn switch(&self) -> Signal<A>

+

Switch between signals.

+ +

This transforms a Signal<Signal<A>> into a Signal<A>. The nested +signal can be thought of as a representation of a switch between different +input signals, that allows one to change the structure of the dependency +graph at run-time. switch provides a way to access the inner value of +the currently active signal.

+ +

The following example demonstrates how to use this to switch between two +input signals based on a Button event stream:

+
+// Button type
+#[derive(Clone, Show)]
+enum Button { A, B };
+
+// The input sinks
+let sink_a = Sink::<i32>::new();
+let sink_b = Sink::<i32>::new();
+
+// The button sink
+let sink_button = Sink::<Button>::new();
+
+// Create the output
+let output = {
+
+    // Hold input sinks in a signal with some initials
+    let channel_a = sink_a.stream().hold(1);
+    let channel_b = sink_b.stream().hold(2);
+
+    // A trivial default channel used before any button event
+    let default_channel = Sink::new().stream().hold(0);
+
+    // Map button to the channel signals, hold with the default channel as
+    // initial value and switch between the signals
+    sink_button
+        .stream()
+        .map(move |b| match b {
+            Button::A => channel_a.clone(),
+            Button::B => channel_b.clone(),
+        })
+        .hold(default_channel)
+        .switch()
+};
+
+// In the beginning, output will come from the default channel
+assert_eq!(output.sample(), 0);
+
+// Let's switch to channel A
+sink_button.send(Button::A);
+assert_eq!(output.sample(), 1);
+
+// And to channel B
+sink_button.send(Button::B);
+assert_eq!(output.sample(), 2);
+
+// The channels can change, too, of course
+for k in 4..13 {
+    sink_b.send(k);
+    assert_eq!(output.sample(), k);
+}
+sink_button.send(Button::A);
+for k in 21..77 {
+    sink_a.send(k);
+    assert_eq!(output.sample(), k);
+}
+
+

Trait Implementations

impl<A> Clone for Signal<A>

fn clone(&self) -> Signal<A>

+

fn clone_from(&mut self, source: &Self)

+

impl<A: Debug + Clone + 'static> Debug for Signal<A>

fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error>

+
+ + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3