<div>Move to haskell-cafe you two.</div><div><br></div><div>(j/k -- I think the discussion is great here. If you also cc&#39;ed -cafe, your points would get higher visibility.)</div><div><br></div><br clear="all">-- Kim-Ee<br>


<br><br><div class="gmail_quote">On Fri, Sep 21, 2012 at 8:53 AM, Ertugrul Söylemez <span dir="ltr">&lt;<a href="mailto:es@ertes.de" target="_blank">es@ertes.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">Heinrich Apfelmus &lt;<a href="mailto:apfelmus@quantentunnel.de">apfelmus@quantentunnel.de</a>&gt; wrote:<br>
<br>
&gt; &gt; Wire is also an Alternative, which allows concise and efficient<br>
&gt; &gt; switching with very little cruft.  The following wire renders &quot;yes&quot;<br>
&gt; &gt; when the &quot;keyDown Space&quot; event happens and &quot;no&quot; otherwise:<br>
&gt; &gt;<br>
&gt; &gt;     pure &quot;yes&quot; . keyDown Space &lt;|&gt; pure &quot;no&quot;<br>
&gt; &gt;<br>
&gt; &gt; Or with the OverloadedStrings extension:<br>
&gt; &gt;<br>
&gt; &gt;     &quot;yes&quot; . keyDown Space &lt;|&gt; &quot;no&quot;<br>
&gt; &gt;<br>
&gt; &gt; All classic (non-wire) FRP implementations need switching or another<br>
&gt; &gt; ad-hoc combinator for this.  If you happen to need switching it&#39;s<br>
&gt; &gt; also a lot simpler using wires:<br>
&gt; &gt;<br>
&gt; &gt;     &quot;please press space&quot; . notE (keyDown Space) --&gt; &quot;thanks&quot;<br>
&gt; &gt;<br>
&gt; &gt; This one waits for the Space key and then outputs &quot;thanks&quot; forever.<br>
&gt; &gt; So far Netwire has the fastest and most elegant way of dealing with<br>
&gt; &gt; events compared to all other libraries I have tried.<br>
&gt;<br>
&gt; These examples look neat!<br>
&gt;<br>
&gt; I&#39;m a bit confused about the model you are using, though. If I<br>
&gt; understand that correctly, you don&#39;t distinguish between events and<br>
&gt; behaviors; rather, you are working with data streams in discrete time<br>
&gt; steps. Still, I don&#39;t quite understand.<br>
<br>
</div>First let me try to put reactive-banana&#39;s model into a data type of my<br>
own, which you might call TimedZipStream.  The name Behavior is easier,<br>
so let me pick that one instead (Time is the type for time deltas):<br>
<br>
    newtype Behavior a =<br>
        Behavior {<br>
          stepBehavior :: Time -&gt; Network (a, Behavior a)<br>
        }<br>
<br>
This is not anywhere near how reactive-banana represents its behaviors,<br>
but just a simplified and less powerful model.  The argument is the time<br>
delta to the last instant.  Communication happens through the Network<br>
monad and is opaque to the user.  The type is an applicative functor<br>
that represents values that can behave differently at each instant.<br>
<br>
My model is similar to Yampas model, where instead of time-varying<br>
values you have time-varying functions, so-called signal functions:<br>
<div class="im"><br>
    newtype SF a b =<br>
</div>        SF {<br>
          stepSF :: Time -&gt; a -&gt; (b, SF a b)<br>
        }<br>
<br>
This is a function from an &#39;a&#39; to a &#39;b&#39; that mutates over time.  There<br>
is a counterpart for classic behaviors, which is when the input type is<br>
fully polymorphic:<br>
<br>
    time :: SF a Time<br>
<br>
SF forms a family of applicative functors, but now there is a direct<br>
path from one signal function to the next, because SF is itself a<br>
category.  No graph, no monad, just plain categorical composition.<br>
Unfortunately to this day Yampa does not provide an Applicative<br>
instance, so you have to use the Arrow interface, which is usually very<br>
ugly.<br>
<br>
The weak spot of both models is events.  They need to be handled using<br>
switchers and other combinators.  Causality, simultaneity and choice all<br>
need to be encoded explicitly.  Event modifiers work outside of the<br>
behavior level.<br>
<br>
What makes Netwire different?  Wire categories are encoded by the<br>
following (simplified) type:<br>
<div class="im"><br>
    newtype Wire e a b =<br>
</div>        Wire {<br>
          stepWire :: Time -&gt; a -&gt; (Either e b, Wire e a b)<br>
        }<br>
<br>
Wires can choose not to output anything, but instead inhibit with a<br>
value of type &#39;e&#39;.  Where i is an inhibiting wire the following<br>
identities hold:<br>
<br>
    x . i = i<br>
    i . x = i<br>
<br>
Furthermore now when &#39;e&#39; is a Monoid Wire is a family of Alternative<br>
functors with the following identities, where x and y produce and i, j<br>
and ij&#39; and inhibit:<br>
<br>
    x &lt;|&gt; y = x<br>
    i &lt;|&gt; y = y<br>
<br>
    i &lt;|&gt; j = ij&#39;<br>
<br>
The ij&#39; wire also inhibits, but mappend-combines the inhibition values.<br>
The empty wire always inhibits with mempty.  The monoid is necessary for<br>
the Category, Applicative and Alternative laws to hold.<br>
<div class="im"><br>
<br>
&gt; What is<br>
&gt;<br>
&gt;      pure &quot;yes&quot; . keyDown Space &lt;|&gt; pure &quot;no&quot;<br>
&gt;<br>
&gt; supposed to mean? If it&#39;s a function Time -&gt; String , how long does it<br>
&gt; have the &quot;yes&quot; value? 439.7 milliseconds? If it&#39;s an event, how often<br>
&gt; does the &quot;no&quot; event fire?<br>
<br>
</div>An event wire is a wire that acts like the identity wire when it<br>
produces, but may choose to inhibit instead:<br>
<div class="im"><br>
    pure &quot;yes&quot; . keyDown Space<br>
<br>
</div>The &#39;keyDown Space&#39; wire acts like the identity wire when the space key<br>
is pressed, otherwise it inhibits.  As a consequence of the above laws<br>
the composition also inhibits.  This is where (&lt;|&gt;) comes in:<br>
<div class="im"><br>
    pure &quot;yes&quot; . keyDown Space &lt;|&gt; pure &quot;no&quot;<br>
<br>
</div>When the left wire inhibits, the right wire takes over.  By definition a<br>
&#39;pure&#39; wire never inhibits.  Notice that in this example I&#39;m assuming<br>
that &#39;keyDown&#39; is a &#39;continuous event&#39;.  That&#39;s where behaviors are<br>
mixed with events.  An event can actually have a duration.<br>
<br>
If &#39;keyDown&#39; would be instantaneous without a duration you could use the<br>
&#39;holdFor&#39; combinator:<br>
<br>
    pure &quot;yes&quot; . holdFor 1 (keyDown Space) &lt;|&gt; pure &quot;no&quot;<br>
<br>
This would also work for a continuous &#39;keyDown&#39; event wire.  Then if you<br>
press the space key for one second, &quot;yes&quot; is displayed for two seconds.<br>
<div class="im"><br>
<br>
&gt; Concerning the other example, I don&#39;t understand what the expression<br>
&gt;<br>
&gt;     &quot;please press space&quot; . notE (keyDown Space)<br>
&gt;<br>
&gt; means. If it&#39;s a function, what value does it have when the key was<br>
&gt; pressed? If it&#39;s an event, how often does it &quot;fire&quot; the string value?<br>
<br>
</div>In this case it doesn&#39;t really matter if &#39;keyDown Space&#39; has a duration<br>
or not.  As soon as it produces once, the switch happens and the next<br>
wire takes over.  There is another name for the (--&gt;) combinator called<br>
&#39;andThen&#39;.<br>
<br>
    x --&gt; y<br>
<br>
As soon as x inhibits, this combination switches to y.<br>
<br>
Side note:  Unlike classic FRP a wire category is not time-bound.  In<br>
fact in the current official release of Netwire (3.1.0) time is actually<br>
an extension.  In Netwire time is back as a primitive, because it makes<br>
time-related wires (the analog to behaviors) much easier to write.  I<br>
have retained the flexibility that your wire can have a time frame<br>
different from real time, though.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
Greets,<br>
Ertugrul<br>
<br>
--<br>
Not to be or to be and (not to be or to be and (not to be or to be and<br>
(not to be or to be and ... that is the list monad.<br>
</div></div><br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br>