aboutsummaryrefslogtreecommitdiff
path: root/carboxyl/struct.Signal.html
diff options
context:
space:
mode:
Diffstat (limited to 'carboxyl/struct.Signal.html')
-rw-r--r--carboxyl/struct.Signal.html245
1 files changed, 245 insertions, 0 deletions
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 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="generator" content="rustdoc">
+ <meta name="description" content="API documentation for the Rust `Signal` struct in crate `carboxyl`.">
+ <meta name="keywords" content="rust, rustlang, rust-lang, Signal">
+
+ <title>carboxyl::Signal - Rust</title>
+
+ <link rel="stylesheet" type="text/css" href="../main.css">
+
+
+
+</head>
+<body class="rustdoc">
+ <!--[if lte IE 8]>
+ <div class="warning">
+ This old browser is unsupported and will most likely display funky
+ things.
+ </div>
+ <![endif]-->
+
+
+
+ <section class="sidebar">
+
+ <p class='location'><a href='index.html'>carboxyl</a></p><script>window.sidebarCurrent = {name: 'Signal', ty: 'struct', relpath: ''};</script><script defer src="sidebar-items.js"></script>
+ </section>
+
+ <nav class="sub">
+ <form class="search-form js-only">
+ <div class="search-container">
+ <input class="search-input" name="search"
+ autocomplete="off"
+ placeholder="Click or press 'S' to search, '?' for more options..."
+ type="search">
+ </div>
+ </form>
+ </nav>
+
+ <section id='main' class="content struct">
+<h1 class='fqn'><span class='in-band'>Struct <a href='index.html'>carboxyl</a>::<wbr><a class='struct' href=''>Signal</a></span><span class='out-of-band'><span id='render-detail'>
+ <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
+ [<span class='inner'>&#x2212;</span>]
+ </a>
+ </span><a id='src-2746' class='srclink' href='../src/carboxyl/signal.rs.html#154-159' title='goto source code'>[src]</a></span></h1>
+<pre class='rust struct'>pub struct Signal&lt;A&gt; {
+ // some fields omitted
+}</pre><div class='docblock'><p>A continuous signal that changes over time.</p>
+
+<p>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&#39;s current value is sampled. (This is
+also called pull semantics in the literature on FRP.)</p>
+
+<p>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.</p>
+
+<h1 id="algebraic-laws" class='section-header'><a
+ href="#algebraic-laws">Algebraic laws</a></h1>
+<p>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.</p>
+
+<h2 id="functor" class='section-header'><a
+ href="#functor">Functor</a></h2>
+<p>Signals form a functor under unary lifting. Thus, the following laws hold:</p>
+
+<ul>
+<li>Preservation of identity: <code>lift!(|x| x, &amp;a) == a</code>,</li>
+<li>Function composition: <code>lift!(|x| g(f(x)), &amp;a) == lift!(g, &amp;lift!(f, &amp;a))</code>.</li>
+</ul>
+
+<h2 id="applicative-functor" class='section-header'><a
+ href="#applicative-functor">Applicative functor</a></h2>
+<p>By extension, using the notion of a signal of a function, signals also
+become an <a href="https://downloads.haskell.org/%7Eghc/latest/docs/html/libraries/base/Control-Applicative.html">applicative</a> using <code>Signal::new</code> as <code>pure</code> and
+<code>|sf, sa| lift!(|f, a| f(a), &amp;sf, &amp;sa)</code> as <code>&lt;*&gt;</code>.</p>
+
+<p><em>TODO: Expand on this and replace the Haskell reference.</em></p>
+</div><h2 id='methods'>Methods</h2><h3 class='impl'><code>impl&lt;A: <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + 'static&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h3><div class='impl-items'><h4 id='method.new' class='method'><code>fn <a href='#method.new' class='fnname'>new</a>(a: A) -&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h4>
+<div class='docblock'><p>Create a constant signal.</p>
+</div><h4 id='method.sample' class='method'><code>fn <a href='#method.sample' class='fnname'>sample</a>(&amp;self) -&gt; A</code></h4>
+<div class='docblock'><p>Sample the current value of the signal.</p>
+</div></div><h3 class='impl'><code>impl&lt;A: <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Send.html' title='core::marker::Send'>Send</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Sync.html' title='core::marker::Sync'>Sync</a> + 'static&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h3><div class='impl-items'><h4 id='method.cyclic' class='method'><code>fn <a href='#method.cyclic' class='fnname'>cyclic</a>&lt;F&gt;(def: F) -&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt; <span class='where'>where F: <a class='trait' href='http://doc.rust-lang.org/nightly/core/ops/trait.FnOnce.html' title='core::ops::FnOnce'>FnOnce</a>(&amp;<a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;) -&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</span></code></h4>
+<div class='docblock'><p>Create a signal with a cyclic definition.</p>
+
+<p>The closure gets an undefined forward-declaration of a signal. It is
+supposed to return a self-referential definition of the same signal.</p>
+
+<p>Sampling the forward-declared signal, before it is properly defined,
+will cause a run-time panic.</p>
+
+<p>This pattern is useful to implement accumulators, counters and other
+loops that depend on the sampling behaviour of a signal before a
+transaction.</p>
+</div><h4 id='method.snapshot' class='method'><code>fn <a href='#method.snapshot' class='fnname'>snapshot</a>&lt;B, C, F&gt;(&amp;self, stream: &amp;<a class='struct' href='../carboxyl/struct.Stream.html' title='carboxyl::Stream'>Stream</a>&lt;B&gt;, f: F) -&gt; <a class='struct' href='../carboxyl/struct.Stream.html' title='carboxyl::Stream'>Stream</a>&lt;C&gt; <span class='where'>where B: <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Send.html' title='core::marker::Send'>Send</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Sync.html' title='core::marker::Sync'>Sync</a> + 'static, C: <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Send.html' title='core::marker::Send'>Send</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Sync.html' title='core::marker::Sync'>Sync</a> + 'static, F: <a class='trait' href='http://doc.rust-lang.org/nightly/core/ops/trait.Fn.html' title='core::ops::Fn'>Fn</a>(A, B) -&gt; C + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Send.html' title='core::marker::Send'>Send</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Sync.html' title='core::marker::Sync'>Sync</a> + 'static</span></code></h4>
+<div class='docblock'><p>Combine the signal with a stream in a snapshot.</p>
+
+<p><code>snapshot</code> 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&#39;s current value and that event using the
+supplied function.</p>
+<pre class='rust rust-example-rendered'>
+<span class='kw'>let</span> <span class='ident'>sink1</span>: <span class='ident'>Sink</span><span class='op'>&lt;</span><span class='ident'>i32</span><span class='op'>&gt;</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='ident'>new</span>();
+<span class='kw'>let</span> <span class='ident'>sink2</span>: <span class='ident'>Sink</span><span class='op'>&lt;</span><span class='ident'>f64</span><span class='op'>&gt;</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='ident'>new</span>();
+<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>events</span> <span class='op'>=</span> <span class='ident'>sink1</span>.<span class='ident'>stream</span>().<span class='ident'>hold</span>(<span class='number'>1</span>)
+ .<span class='ident'>snapshot</span>(<span class='kw-2'>&amp;</span><span class='ident'>sink2</span>.<span class='ident'>stream</span>(), <span class='op'>|</span><span class='ident'>a</span>, <span class='ident'>b</span><span class='op'>|</span> (<span class='ident'>a</span>, <span class='ident'>b</span>))
+ .<span class='ident'>events</span>();
+
+<span class='comment'>// Updating its signal does not cause the snapshot to fire</span>
+<span class='ident'>sink1</span>.<span class='ident'>send</span>(<span class='number'>4</span>);
+
+<span class='comment'>// However sending an event down the stream does</span>
+<span class='ident'>sink2</span>.<span class='ident'>send</span>(<span class='number'>3.0</span>);
+<span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>events</span>.<span class='ident'>next</span>(), <span class='prelude-val'>Some</span>((<span class='number'>4</span>, <span class='number'>3.0</span>)));
+</pre>
+</div></div><h3 class='impl'><code>impl&lt;A: <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Send.html' title='core::marker::Send'>Send</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/marker/trait.Sync.html' title='core::marker::Sync'>Sync</a> + 'static&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;<a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;&gt;</code></h3><div class='impl-items'><h4 id='method.switch' class='method'><code>fn <a href='#method.switch' class='fnname'>switch</a>(&amp;self) -&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h4>
+<div class='docblock'><p>Switch between signals.</p>
+
+<p>This transforms a <code>Signal&lt;Signal&lt;A&gt;&gt;</code> into a <code>Signal&lt;A&gt;</code>. 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. <code>switch</code> provides a way to access the inner value of
+the currently active signal.</p>
+
+<p>The following example demonstrates how to use this to switch between two
+input signals based on a <code>Button</code> event stream:</p>
+<pre class='rust rust-example-rendered'>
+<span class='comment'>// Button type</span>
+<span class='attribute'>#[<span class='ident'>derive</span>(<span class='ident'>Clone</span>, <span class='ident'>Show</span>)]</span>
+<span class='kw'>enum</span> <span class='ident'>Button</span> { <span class='ident'>A</span>, <span class='ident'>B</span> };
+
+<span class='comment'>// The input sinks</span>
+<span class='kw'>let</span> <span class='ident'>sink_a</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='op'>&lt;</span><span class='ident'>i32</span><span class='op'>&gt;</span>::<span class='ident'>new</span>();
+<span class='kw'>let</span> <span class='ident'>sink_b</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='op'>&lt;</span><span class='ident'>i32</span><span class='op'>&gt;</span>::<span class='ident'>new</span>();
+
+<span class='comment'>// The button sink</span>
+<span class='kw'>let</span> <span class='ident'>sink_button</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='op'>&lt;</span><span class='ident'>Button</span><span class='op'>&gt;</span>::<span class='ident'>new</span>();
+
+<span class='comment'>// Create the output</span>
+<span class='kw'>let</span> <span class='ident'>output</span> <span class='op'>=</span> {
+
+ <span class='comment'>// Hold input sinks in a signal with some initials</span>
+ <span class='kw'>let</span> <span class='ident'>channel_a</span> <span class='op'>=</span> <span class='ident'>sink_a</span>.<span class='ident'>stream</span>().<span class='ident'>hold</span>(<span class='number'>1</span>);
+ <span class='kw'>let</span> <span class='ident'>channel_b</span> <span class='op'>=</span> <span class='ident'>sink_b</span>.<span class='ident'>stream</span>().<span class='ident'>hold</span>(<span class='number'>2</span>);
+
+ <span class='comment'>// A trivial default channel used before any button event</span>
+ <span class='kw'>let</span> <span class='ident'>default_channel</span> <span class='op'>=</span> <span class='ident'>Sink</span>::<span class='ident'>new</span>().<span class='ident'>stream</span>().<span class='ident'>hold</span>(<span class='number'>0</span>);
+
+ <span class='comment'>// Map button to the channel signals, hold with the default channel as</span>
+ <span class='comment'>// initial value and switch between the signals</span>
+ <span class='ident'>sink_button</span>
+ .<span class='ident'>stream</span>()
+ .<span class='ident'>map</span>(<span class='kw'>move</span> <span class='op'>|</span><span class='ident'>b</span><span class='op'>|</span> <span class='kw'>match</span> <span class='ident'>b</span> {
+ <span class='ident'>Button</span>::<span class='ident'>A</span> <span class='op'>=&gt;</span> <span class='ident'>channel_a</span>.<span class='ident'>clone</span>(),
+ <span class='ident'>Button</span>::<span class='ident'>B</span> <span class='op'>=&gt;</span> <span class='ident'>channel_b</span>.<span class='ident'>clone</span>(),
+ })
+ .<span class='ident'>hold</span>(<span class='ident'>default_channel</span>)
+ .<span class='ident'>switch</span>()
+};
+
+<span class='comment'>// In the beginning, output will come from the default channel</span>
+<span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>output</span>.<span class='ident'>sample</span>(), <span class='number'>0</span>);
+
+<span class='comment'>// Let&#39;s switch to channel A</span>
+<span class='ident'>sink_button</span>.<span class='ident'>send</span>(<span class='ident'>Button</span>::<span class='ident'>A</span>);
+<span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>output</span>.<span class='ident'>sample</span>(), <span class='number'>1</span>);
+
+<span class='comment'>// And to channel B</span>
+<span class='ident'>sink_button</span>.<span class='ident'>send</span>(<span class='ident'>Button</span>::<span class='ident'>B</span>);
+<span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>output</span>.<span class='ident'>sample</span>(), <span class='number'>2</span>);
+
+<span class='comment'>// The channels can change, too, of course</span>
+<span class='kw'>for</span> <span class='ident'>k</span> <span class='kw'>in</span> <span class='number'>4</span>..<span class='number'>13</span> {
+ <span class='ident'>sink_b</span>.<span class='ident'>send</span>(<span class='ident'>k</span>);
+ <span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>output</span>.<span class='ident'>sample</span>(), <span class='ident'>k</span>);
+}
+<span class='ident'>sink_button</span>.<span class='ident'>send</span>(<span class='ident'>Button</span>::<span class='ident'>A</span>);
+<span class='kw'>for</span> <span class='ident'>k</span> <span class='kw'>in</span> <span class='number'>21</span>..<span class='number'>77</span> {
+ <span class='ident'>sink_a</span>.<span class='ident'>send</span>(<span class='ident'>k</span>);
+ <span class='macro'>assert_eq</span><span class='macro'>!</span>(<span class='ident'>output</span>.<span class='ident'>sample</span>(), <span class='ident'>k</span>);
+}
+</pre>
+</div></div><h2 id='implementations'>Trait Implementations</h2><h3 class='impl'><code>impl&lt;A&gt; <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> for <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h3><div class='impl-items'><h4 id='method.clone' class='method'><code>fn <a href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html#method.clone' class='fnname'>clone</a>(&amp;self) -&gt; <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h4>
+<h4 id='method.clone_from' class='method'><code>fn <a href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html#method.clone_from' class='fnname'>clone_from</a>(&amp;mut self, source: &amp;Self)</code></h4>
+</div><h3 class='impl'><code>impl&lt;A: <a class='trait' href='http://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html' title='core::fmt::Debug'>Debug</a> + <a class='trait' href='http://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a> + 'static&gt; <a class='trait' href='http://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html' title='core::fmt::Debug'>Debug</a> for <a class='struct' href='../carboxyl/struct.Signal.html' title='carboxyl::Signal'>Signal</a>&lt;A&gt;</code></h3><div class='impl-items'><h4 id='method.fmt' class='method'><code>fn <a href='http://doc.rust-lang.org/nightly/core/fmt/trait.Debug.html#method.fmt' class='fnname'>fmt</a>(&amp;self, fmt: &amp;mut <a class='struct' href='http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html' title='core::fmt::Formatter'>Formatter</a>) -&gt; <a class='enum' href='http://doc.rust-lang.org/nightly/core/result/enum.Result.html' title='core::result::Result'>Result</a>&lt;<a href='http://doc.rust-lang.org/nightly/std/primitive.tuple.html'>()</a>, <a class='struct' href='http://doc.rust-lang.org/nightly/core/fmt/struct.Error.html' title='core::fmt::Error'>Error</a>&gt;</code></h4>
+</div></section>
+ <section id='search' class="content hidden"></section>
+
+ <section class="footer"></section>
+
+ <div id="help" class="hidden">
+ <div class="shortcuts">
+ <h1>Keyboard shortcuts</h1>
+ <dl>
+ <dt>?</dt>
+ <dd>Show this help dialog</dd>
+ <dt>S</dt>
+ <dd>Focus the search field</dd>
+ <dt>&larrb;</dt>
+ <dd>Move up in search results</dd>
+ <dt>&rarrb;</dt>
+ <dd>Move down in search results</dd>
+ <dt>&#9166;</dt>
+ <dd>Go to active search result</dd>
+ </dl>
+ </div>
+ <div class="infos">
+ <h1>Search tricks</h1>
+ <p>
+ Prefix searches with a type followed by a colon (e.g.
+ <code>fn:</code>) to restrict the search to a given type.
+ </p>
+ <p>
+ Accepted types are: <code>fn</code>, <code>mod</code>,
+ <code>struct</code>, <code>enum</code>,
+ <code>trait</code>, <code>typedef</code> (or
+ <code>tdef</code>).
+ </p>
+ <p>
+ Search functions by type signature (e.g.
+ <code>vec -> usize</code>)
+ </p>
+ </div>
+ </div>
+
+
+
+ <script>
+ window.rootPath = "../";
+ window.currentCrate = "carboxyl";
+ window.playgroundUrl = "";
+ </script>
+ <script src="../jquery.js"></script>
+ <script src="../main.js"></script>
+
+ <script async src="../search-index.js"></script>
+</body>
+</html> \ No newline at end of file