<div dir="ltr">Hi Ryan,<br><br>Thanks very much for these explanations.&nbsp; Clear and right on!<br><br>Best regards,&nbsp; - Conal<br><br>P.S. I&#39;ll be at ICFP and am looking forward to seeing folks there.<br><br><div class="gmail_quote">
2008/9/16 Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The key insight is that Behavior a is not necessarily a time function;<br>
it&#39;s abstract. &nbsp;But you can treat it as if it was one by observing it<br>
with &quot;at&quot;.<br>
<br>
In Conal&#39;s paper, the internal type of behavior is:<br>
<br>
&gt; -- composition of types; like (.) at the type level<br>
&gt; newtype O h g a = O (h (g a))<br>
<br>
&gt; -- function type that can directly observe some constant functions<br>
&gt; data Fun t a = K a | Fun (t -&gt; a)<br>
<br>
&gt; -- Behavior a ~~ Reactive (Fun Time a)<br>
&gt; type Behavior = Reactive `O` Fun Time<br>
<br>
&gt; -- Reactive has a current value and an event stream of values to switch to at particular times<br>
&gt; -- Then an event is just a reactive that might not have a current value until some time in the future.<br>
&gt; data Reactive a = Stepper a (Event a)<br>
&gt; newtype Event a = Ev (Future (Reactive a))<br>
<br>
Now, at the internal level, you can write the primitive &quot;time&quot; as<br>
<br>
&gt; time :: Behavior Time<br>
&gt; time = O (pure (Fun id))<br>
<br>
with &quot;pure&quot; from the Applicative instance for Reactive:<br>
<br>
&gt; pure x = Stepper x never<br>
<br>
&quot;never&quot; is a future that never occurs, so the reactive value never changes.<br>
<br>
From a users&#39; point of view, all this is invisible--you only get a few<br>
observation functions (including &quot;at&quot;). &nbsp;Internally, however, constant<br>
behaviors, or behaviors that contain &quot;steps&quot; that are constant, can be<br>
evaluated extremely quickly; once the behavior returns K x, you know<br>
that the result can&#39;t change until the next event in the reactive<br>
stream. &nbsp;You only need to continuously evaluate the behavior if you<br>
get a &quot;Fun&quot; result. &nbsp;See sinkB on page 9 of the paper to understand<br>
how this is used to improve performance.<br>
<br>
The semantic function &quot;at&quot; drives the model; it allows you to describe<br>
the laws for the library to fulfill very succinctly:<br>
<br>
at (fmap f x) = fmap f (at x)<br>
at (pure x) = pure x<br>
at (f &lt;*&gt; x) = at f &lt;*&gt; at x<br>
at (return x) = return x<br>
at (m &gt;&gt;= f) = at m &gt;&gt;= at . f<br>
etc.<br>
<br>
Similarily, for Futures, we have &quot;force :: Future a -&gt; (Time, a)&quot;<br>
<br>
force (fmap f z) = (t, f x) where (t,x) = force z<br>
force (pure x) = (minBound, x)<br>
force (ff &lt;*&gt; fx) = (max tf tx, f x) where (tf, f) = force ff ; (tx,<br>
x) = force fx<br>
force (return x) = (minBound, x)<br>
force (m &gt;&gt;= f) = (max tm tx, x) where (tm, v) = force m; (tx, x) = force (f v)<br>
etc.<br>
<br>
This gives the library user solid ground to stand on when reasoning<br>
about their code; it should do what they expect. &nbsp;And it gives the<br>
library author a very strong goal to shoot for: just fulfill these<br>
laws, and the code is correct! &nbsp;This allows radical redesigns of the<br>
internals of the system while maintaining a consistent and intuitive<br>
interface that reuses several classes that the user is hopefully<br>
already familiar with: monoids, functors, applicative functors, and<br>
monads.<br>
<br>
 &nbsp;-- ryan<br>
<br>
2008/9/16 Daryoush Mehrtash &lt;<a href="mailto:dmehrtash@gmail.com">dmehrtash@gmail.com</a>&gt;:<br>
<div><div></div><div class="Wj3C7c">&gt; ø I don&#39;t follow the &quot;at&quot; and &nbsp;&quot;type B a&quot;. &nbsp;&quot;Behavior a&quot; itself is a<br>
&gt; time function. &nbsp; At least in the version of the code that was<br>
&gt; developed in Pual Hudak&#39;s Haskell School of Expression it was defined<br>
&gt; as:<br>
&gt;<br>
&gt;&gt; newtype Behavior a<br>
&gt;&gt; &nbsp; = Behavior (([Maybe UserAction],[Time]) -&gt; [a])<br>
&gt;<br>
&gt; In a function like time you can see that the &quot;at&quot; function makes things simpler.<br>
&gt;<br>
&gt; In the original version &nbsp;time was defined as:<br>
&gt;<br>
&gt;&gt; time :: Behavior Time<br>
&gt;&gt; time = Behavior (\(_,ts) -&gt; ts)<br>
&gt;<br>
&gt; In Conal&#39;s paper<br>
&gt;<br>
&gt; time :: Behavior Time<br>
&gt; at time = id<br>
&gt;<br>
&gt; Comparing the two implementation of the time, it seems to me that &quot;at&quot;<br>
&gt; and &quot;type B a&quot; has put the design on a more solid ground. &nbsp;But I don&#39;t<br>
&gt; quite understand the thought process, or the principal behind what is<br>
&gt; happening.<br>
&gt;<br>
&gt; daryoush<br>
&gt;<br>
&gt;<br>
&gt; On Mon, Sep 15, 2008 at 10:46 AM, Ryan Ingram &lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt; wrote:<br>
&gt;&gt; Here&#39;s a quick overview that might help you.<br>
&gt;&gt;<br>
&gt;&gt; For a reactive behavior, we have two types to think about:<br>
&gt;&gt;<br>
&gt;&gt; type B a = Time -&gt; a<br>
&gt;&gt; &nbsp; &nbsp;(the semantic domain)<br>
&gt;&gt;<br>
&gt;&gt; data Behavior a = ?<br>
&gt;&gt; &nbsp; &nbsp;(the library&#39;s implementation).<br>
&gt;&gt; at :: Behavior a -&gt; B a<br>
&gt;&gt; &nbsp; &nbsp;(observation function)<br>
&gt;&gt;<br>
&gt;&gt; This is really just classic &quot;information hiding&quot; as you would do with<br>
&gt;&gt; any abstract data type. &nbsp;Consider a simple &quot;stack&quot; data structure that<br>
&gt;&gt; supports push and pop.<br>
&gt;&gt;<br>
&gt;&gt;&gt; data S a = S<br>
&gt;&gt;&gt; &nbsp; &nbsp; { popS :: Maybe (a, S a)<br>
&gt;&gt;&gt; &nbsp; &nbsp; , pushS :: a -&gt; S a<br>
&gt;&gt;&gt; &nbsp; &nbsp; }<br>
&gt;&gt;<br>
&gt;&gt;&gt; data Stack a = ?<br>
&gt;&gt;&gt; observeStack :: Stack a -&gt; S a<br>
&gt;&gt;<br>
&gt;&gt; As a library user, you don&#39;t really care about the implementation of<br>
&gt;&gt; Stack, just as a user of Conal&#39;s library doesn&#39;t really care about the<br>
&gt;&gt; implementation of Behavior. &nbsp;What you *do* care about is that you can<br>
&gt;&gt; think about it in the simpler terms of &quot;Time -&gt; a&quot; which is the model<br>
&gt;&gt; he has chosen.<br>
&gt;&gt;<br>
&gt;&gt; The rest of the library design comes from taking that model and<br>
&gt;&gt; thinking about what typeclasses and operations &quot;Time -&gt; a&quot; should<br>
&gt;&gt; support, and creating typeclass morphisms between Behavior a and B a<br>
&gt;&gt; where necessary. &nbsp;For example:<br>
&gt;&gt;<br>
&gt;&gt;&gt; -- This makes (r -&gt; a) into a functor over a; it is a generalization of Time -&gt; a<br>
&gt;&gt;&gt; instance Functor ((-&gt;) r) where<br>
&gt;&gt;&gt; &nbsp; &nbsp;-- fmap :: (a -&gt; b) -&gt; (r -&gt; a) -&gt; (r -&gt; b)<br>
&gt;&gt;&gt; &nbsp; &nbsp;fmap f x = \r -&gt; f (x r)<br>
&gt;&gt;&gt; &nbsp; &nbsp;-- or, &quot;fmap = (.)&quot;, if you&#39;re golfing :)<br>
&gt;&gt;<br>
&gt;&gt; In order for the morphism between B and Behavior to make sense, you<br>
&gt;&gt; want this law to hold:<br>
&gt;&gt; &nbsp; fmap f (at behavior) = at (fmap f behavior)<br>
&gt;&gt; for all behavior :: Behavior a.<br>
&gt;&gt;<br>
&gt;&gt; The fmap on the left applies to B which is (Time -&gt;); the fmap on the<br>
&gt;&gt; right applies to Behavior.<br>
&gt;&gt;<br>
&gt;&gt; Conal writes this law more elegantly like this:<br>
&gt;&gt;&gt; instance(semantic) Functor Behavior where<br>
&gt;&gt;&gt; &nbsp; &nbsp;fmap f . at = at . fmap f<br>
&gt;&gt;<br>
&gt;&gt; As long as you as the user can think about behaviors generally as<br>
&gt;&gt; functions of Time, you can ignore the implementation details, and<br>
&gt;&gt; things that you expect to work should work. &nbsp;This drives the design of<br>
&gt;&gt; the entire library, with similar morphisms over many typeclasses<br>
&gt;&gt; between Event and E, Reactive and B, etc.<br>
&gt;&gt;<br>
&gt;&gt; &nbsp;-- ryan<br>
&gt;&gt;<br>
&gt;&gt; On Mon, Sep 15, 2008 at 10:13 AM, Daryoush Mehrtash &lt;<a href="mailto:dmehrtash@gmail.com">dmehrtash@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; Interestingly, I was trying to read his paper when I realized that I<br>
&gt;&gt;&gt; needed to figure out the meaning of denotational model, semantic<br>
&gt;&gt;&gt; domain, semantic functions. &nbsp;Other Haskell books didn&#39;t talk about<br>
&gt;&gt;&gt; design in those terms, but obviously for him this is how he is driving<br>
&gt;&gt;&gt; his design. &nbsp; I am looking for a simpler tutorial, text book like<br>
&gt;&gt;&gt; reference on the topic.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Daryoush<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Mon, Sep 15, 2008 at 1:33 AM, Ryan Ingram &lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt; I recommend reading Conal Elliott&#39;s &quot;Efficient Functional Reactivity&quot;<br>
&gt;&gt;&gt;&gt; paper for an in-depth real-world example.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; <a href="http://www.conal.net/papers/simply-reactive" target="_blank">http://www.conal.net/papers/simply-reactive</a><br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; &nbsp;-- ryan<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; On Sun, Sep 14, 2008 at 11:31 AM, Daryoush Mehrtash &lt;<a href="mailto:dmehrtash@gmail.com">dmehrtash@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt;&gt; I have been told that for a Haskell/Functional programmer the process<br>
&gt;&gt;&gt;&gt;&gt; of design starts with defining Semantic Domain, Function, and<br>
&gt;&gt;&gt;&gt;&gt; denotational model of the problem. &nbsp;I have done some googling on the<br>
&gt;&gt;&gt;&gt;&gt; topic but haven&#39;t found a good reference on it. &nbsp; &nbsp;I would appreciate<br>
&gt;&gt;&gt;&gt;&gt; any good references on the topic.<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; thanks,<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; daryoush<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; ps. &nbsp;I have found referneces like<br>
&gt;&gt;&gt;&gt;&gt; <a href="http://en.wikibooks.org/wiki/Haskell/Denotational_semantics" target="_blank">http://en.wikibooks.org/wiki/Haskell/Denotational_semantics</a> &nbsp;which<br>
&gt;&gt;&gt;&gt;&gt; talks about semantic domain for &quot;the Haskell programs 10, 9+1, 2*5&quot;<br>
&gt;&gt;&gt;&gt;&gt; which doesn&#39;t do any good for me. &nbsp; &nbsp;I need something with a more real<br>
&gt;&gt;&gt;&gt;&gt; examples.<br>
&gt;&gt;&gt;&gt;&gt; _______________________________________________<br>
&gt;&gt;&gt;&gt;&gt; Haskell-Cafe mailing list<br>
&gt;&gt;&gt;&gt;&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt;&gt;&gt;&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
</div></div><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>