I see. So you&#39;re current implementation is not push, is it? The original pull implementation in Fran also used Maybe events, but that was considered inefficient. How is Reactive Banana better then Fran then?<div><br></div>
<div>--Bartosz<br><br><div class="gmail_quote">On Tue, Jun 26, 2012 at 1:40 AM, Heinrich Apfelmus <span dir="ltr">&lt;<a href="mailto:apfelmus@quantentunnel.de" target="_blank">apfelmus@quantentunnel.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">Bartosz Milewski wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks, Heinrich. I looked at the examples and at the references you<br>
provided. I understand the semantic model, so I guess I&#39;m mostly trying to<br>
understand the implementation.<br>
</blockquote>
<br></div>
Ok. As I mentioned, if you just want to use the library there is no need to understand the implementation.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Conal&#39;s paper was mostly about refining data<br>
structures in order to provide better implementation. It&#39;s all beautiful up<br>
to the point where he introduces the unamb hack. How did you manage to work<br>
around this problem and implement event merging efficiently?<br>
</blockquote>
<br></div>
Essentially, Conal implements events as<br>
<br>
    type Event a = [(Time,a)]<br>
<br>
The trouble is that when merging events, this representation forces you to wait for both events. In other words, the pattern match<br>
<br>
    union ((t1,x1):e1) ((t2,x2):e2) = ...<br>
<br>
needs to know the times of occurrences of both events before it can return the earlier one. The trouble is that the  merge  function should have returned the earlier one right away, before knowing exactly when the later one happens. The purpose of the  unamb  hack is circumvent that problem.<br>

<br>
<br>
Reactive-banana&#39;s very simple solution to this problem is to represent events as<br>
<br>
    type Event a = [(Time, Maybe a)]<br>
<br>
and impose the additional invariant that all events in your program are &quot;synchronized&quot;, in the sense that they indicate their occurrences at the same times^1. If they don&#39;t occur at that time, they use  Nothing . Then, you can implement  merge  simply as<br>

<br>
    union ((t1,x1):e1) ((t2,x2):e2) = -- we always have  t1 = t2<br>
        (t1, combine x1 x2) : union e1 e2<br>
        where<br>
        combine (Just x) Nothing  = Just x   -- only left occurs<br>
        combine Nothing  (Just y) = Just y   -- only right occurs<br>
        combine (Just x) (Just y) = Just x   -- simultaneous occurrence<br>
        combine Nothing  Nothing  = Nothing  -- neither occurs<br>
<br>
Since the times are given globally, we can also remove them and obtain<br>
<br>
    type Event a = [Maybe a]<br>
<br>
This is how  Reactive.Banana.Model  does it.<br>
<br>
<br>
Of course, keeping track of a lot of  Nothing  is something that can be optimized. The optimization to apply here is to transform the implementation into a push-driven style. I haven&#39;t published the details yet, but some design notes can be found here.<br>

<br>
<a href="http://apfelmus.nfshost.com/blog/2011/04/24-frp-push-driven-sharing.html" target="_blank">http://apfelmus.nfshost.com/<u></u>blog/2011/04/24-frp-push-<u></u>driven-sharing.html</a><br>
<br>
<br>
^1: Note that the times do not need to follow a uniform time step.<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
Best regards,<br>
Heinrich Apfelmus<br>
<br>
--<br>
<a href="http://apfelmus.nfshost.com" target="_blank">http://apfelmus.nfshost.com</a><br>
<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
<br>
-- <br>
You received this message because you are subscribed to the Google Groups &quot;Haskell-cafe&quot; group.<br>
To post to this group, send email to <a href="mailto:haskell-cafe@googlegroups.com" target="_blank">haskell-cafe@googlegroups.com</a>.<br>
To unsubscribe from this group, send email to <a href="mailto:haskell-cafe%2Bunsubscribe@googlegroups.com" target="_blank">haskell-cafe+unsubscribe@<u></u>googlegroups.com</a>.<br>
For more options, visit this group at <a href="http://groups.google.com/group/haskell-cafe?hl=en" target="_blank">http://groups.google.com/<u></u>group/haskell-cafe?hl=en</a>.<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>[:Bartosz:]<br>
</div>