<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; comonad</title>
	<atom:link href="http://conal.net/blog/tag/comonad/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>Functional interactive behavior</title>
		<link>http://conal.net/blog/posts/functional-interactive-behavior</link>
		<comments>http://conal.net/blog/posts/functional-interactive-behavior#comments</comments>
		<pubDate>Wed, 10 Dec 2008 09:26:50 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[interaction]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=70</guid>
		<description><![CDATA[In a previous post, I presented a fundamental reason why classic FRP does not fit interactive behavior, which is that the semantic model captures only the influence of time and not other input. I also gave a simple alternative, with a simple and general model for temporal and spatial transformation, in which input behavior is [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Functional interactive behavior

Tags: FRP, functional reactive programming, interaction

URL: http://conal.net/blog/posts/functional-interactive-behavior/

-->

<!-- references -->

<!-- teaser -->

<p>In a previous post, I presented a fundamental reason <em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">why classic FRP does not fit interactive behavior</a></em>, which is that the semantic model captures only the influence of time and not other input.
I also gave a simple alternative, with a simple and general model for temporal and spatial transformation, in which input behavior is transformed inversely to the transformation of output behavior.</p>

<p>The semantic model I suggested is the same as used in &#8220;Arrow FRP&#8221;, from <a href="http://conal.net/papers/genuinely-functional-guis.pdf" title="Paper: &quot;Genuinely Functional User Interfaces&quot;">Fruit</a> and <a href="http://haskell.org/haskellwiki/Yampa" title="Wiki page">Yampa</a>.
I want, however, a more convenient and efficient way to package up that model, which is the subject of the post you are reading now.</p>

<p>Next, we took a close look at one awkward aspect of classic FRP for interactive behavior, namely the need to <a href="http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/" title="blog post">trim inputs</a>, and how trimming relates to <a href="http://conal.net/blog/tag/comonad/">comonadic</a> FRP.
The <code>trim</code> function allows us to define multi-phase interactive behaviors correctly and efficiently, but its use is tedious and is easy to get wrong.
It thus fails to achieve what I want from functional programming in general and FRP in particular, which is to enable writing simple, natural descriptions, free of mechanical details.</p>

<p>The current post hides and automates the mechanics of trimming, so that the intent of an interactive behavior can be expressed directly and executed correctly and efficiently.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-70"></span></p>

<p>As before, I&#8217;ll adopt two abbreviations, for succinctness:</p>

<pre><code>type B = Behavior
type E = Event
</code></pre>

<h3>Safe and easy trimming</h3>

<p><a href="http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/" title="blog post">Previously</a>, I defined an interactive cat behavior as follows:</p>

<pre><code>cat3 :: B World -&gt; B Cat
cat3 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trimf wake   world) `mappend`
                (uncurry eat   &lt;$&gt; trimf hunger world))
</code></pre>

<p>I&#8217;d really like to write the following</p>

<pre><code>-- ideal:
cat4 = sleep `switcher` ((prowl &lt;$&gt; wake) `mappend` (eat &lt;$&gt; hunger)) 
</code></pre>

<p>Let&#8217;s see how close we can get.</p>

<p>I can see right off I&#8217;ll have to replace or generalize <code>switcher</code>.
For now, I&#8217;ll replace it:</p>

<pre><code>switcherf :: (B i -&gt; B o)
          -&gt; (B i -&gt; E (B i -&gt; B o))
          -&gt; (B i -&gt; B o)
</code></pre>

<p>This function will have to manage trimming:</p>

<pre><code>bf `switcherf` ef =  i -&gt;
  bf i `switcher` (uncurry ($) &lt;$&gt; trimf ef i)
</code></pre>

<p>I won&#8217;t have to replace <code>mappend</code>, since it&#8217;s a method and so can have a variety of types.
In this case, <code>mappend</code> applies to a function from behaviors to events.
Fortunately, the function monoid is exactly what we need:</p>

<pre><code>instance Monoid b =&gt; Monoid (a -&gt; b) where
  mempty        = const mempty
  f `mappend` g =  a -&gt; f a `mappend` f b
</code></pre>

<p>or the more lovely standard form for applicative functors:</p>

<pre><code>instance Monoid b =&gt; Monoid (a -&gt; b) where
  mempty  = pure   mempty
  mappend = liftA2 mappend
</code></pre>

<p>The use of <code>(&lt;$&gt;)</code> (i.e., <code>fmap</code>) in <code>cat4</code> above won&#8217;t work.
We want instead to <code>fmap</code> inside the <em>result</em> of a function from behaviors to events.
Using the style of <a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">semantic editor combinators</a>, we get the following definition, which is fairly close to our ideal:</p>

<pre><code>cat4 = sleep `switcherf`
         ((result.fmap) prowl wake `mappend` (result.fmap) eat hunger)
</code></pre>

<h3>Generalized switching</h3>

<p>To generalize <code>switcher</code>, introduce a new type class:</p>

<pre><code>class Switchable b e where switcher :: b -&gt; e b -&gt; b
</code></pre>

<p>The original Reactive <code>switcher</code> is a special case:</p>

<pre><code>instance Switchable (B a) E where switcher = R.switcher
</code></pre>

<p>We can switch among tuples and among other containers of switchables.
For instance,</p>

<pre><code>instance (Functor e, Switchable b e, Switchable b' e)
      =&gt; Switchable (b,b') e where
  (b,b') `switcher` e = ( b  `switcher` (fst &lt;$&gt; e)
                        , b' `switcher` (snd &lt;$&gt; e) )
</code></pre>

<h3>Temporal values</h3>

<p>Looking through the examples above, all we really had to do with the input behavior was to compute all remainders.
I used</p>

<pre><code>duplicate :: B a -&gt; B (B a)
</code></pre>

<p>More generally,</p>

<pre><code>class Temporal a where remainders :: a -&gt; B a
</code></pre>

<p>Behaviors and events are included as a special case,</p>

<pre><code>instance Temporal (B a) where remainders = duplicate

instance Temporal (E a) where remainders = ...
</code></pre>

<p>Temporal values combine without losing their individuality, which allows efficient change-driven evaluation as in <em><a href="http://conal.net/blog/posts/simply-efficient-functional-reactivity/" title="blog post">Simply efficient functional reactivity</a></em>:</p>

<pre><code>instance (Temporal a, Temporal b) =&gt; Temporal (a,b) where
  remainders (a,b) = remainders a `zip` remainders b
</code></pre>

<p>Similarly for other triples and other data structures.</p>

<p>Sometimes it&#8217;s handy to carry static information along with dynamic information.
Static types can be made trivially temporal:</p>

<pre><code>instance Temporal Bool where remainders = pure
instance Temporal Int  where remainders = pure
-- etc
</code></pre>

<p>With this <code>Temporal</code> class, the trimming definitions above have more general types.</p>

<pre><code>trim  :: Temporal i =&gt; E o -&gt; i -&gt; E (o, i)

trimf :: Temporal i =&gt; (i -&gt; E o) -&gt; (i -&gt; E (o, i))
</code></pre>

<p>As does function switching:</p>

<pre><code>switcherf :: (Temporal i, Switchable o E) =&gt;
             (i -&gt; o) -&gt; (i -&gt; E (i -&gt; o)) -&gt; i -&gt; o
</code></pre>

<h3>Types for functional interactive behavior</h3>

<p>We&#8217;ve gotten almost to my ideal cat definition.
We cannot, however, use <code>switcher</code> or <code>(&lt;$&gt;)</code> here with functions from behaviors to behaviors, because the types don&#8217;t fit.</p>

<p>To cross the last gap, let&#8217;s define new types corresponding to the idioms we&#8217;ve seen repeatedly above.</p>

<pre><code>-- First try
type i :~&gt; o = BI (B i -&gt; B o)
type i :-&gt; o = EI (B i -&gt; E o)
</code></pre>

<p>Or, using <a href="http://haskell.org/haskellwiki/TypeCompose" title="Wiki page">type composition</a>:</p>

<pre><code>-- Second try
type (:~&gt;) i = (-&gt;) (B i) :. B
type (:-&gt;) i = (-&gt;) (B i) :. E
</code></pre>

<p>The advantage of type composition is that we get some useful definitions for free, including <code>Functor</code> and <code>Applicative</code> instances.</p>

<p>However, there&#8217;s a problem with both versions.
They limit us to a single behavior as input.
A realistic interactive environment has many inputs, including a mixture of behaviors and events.</p>

<p>In Yampa, that mixture is combined into a single behavior, leading to two difficulties:</p>

<ul>
<li>The distinction between behaviors and events gets lost, as well as (I think) accurate and minimal-latency event detection and response.</li>
<li>The bundled input environment changes whenever any component changes, leading to everything getting recomputed and redisplayed when anything changes.</li>
</ul>

<p>To avoid these problems, I&#8217;ll take a different approach.
Generalize inputs from behaviors to arbitrary <code>Temporal</code> values, which include behaviors, events and tuples and structures of temporal values.</p>

<p>The types for interactive behaviors and interactive events are</p>

<pre><code>type (:~&gt;) i = (-&gt;) i :. B
type (:-&gt;) i = (-&gt;) i :. E
</code></pre>

<p>So <code>i :~&gt; o</code> is like <code>i -&gt; B o</code>, and <code>i :-&gt; o</code> is like <code>i -&gt; E o</code>.</p>

<p>Switching for interactive behaviors wraps the <code>switcherf</code> function from above:</p>

<pre><code>instance Temporal i =&gt; Switchable (i :~&gt; o) ((:-&gt;) i) where
  switcher = inO2 $  bf ef -&gt; bf `switcherf` (result.fmap) unO ef
</code></pre>

<p>The <code>inO2</code> and <code>unO</code> functions from <a href="http://haskell.org/haskellwiki/TypeCompose" title="Wiki page">TypeCompose</a> just manipulate <code>newtype</code> wrappers.
See <em><a href="http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/" title="blog post">Prettier functions for wrapping and wrapping</a></em>.</p>

<p>This definition is actually more general than the type given here.
For instance, it can be used to switch between interactive <em>events</em> as well as interactive <em>behaviors</em>.
To see the generalization, first abstract out the commonality between <code>(:~&gt;)</code> and <code>(:-&gt;)</code>:</p>

<pre><code>type i :-&gt;. f = (-&gt;) i :. f

type (:~&gt;) i = i :-&gt;. B
type (:-&gt;) i = i :-&gt;. E
</code></pre>

<p>The same instance code but with a more general type:</p>

<pre><code>instance (Temporal i, Switchable (f o) E)
      =&gt; Switchable ((i :-&gt;. f) o) ((:-&gt;) i) where
  switcher = inO2 $  bf ef -&gt; bf `switcherf` (result.fmap) unO ef
</code></pre>

<p>We can also switch between interactive <em>collections</em> of behaviors and events, though not with the <code>(:-&gt;.)</code> wrapping.</p>

<h3>Where are we?</h3>

<p>Almost all of the pieces are in place now.
Another post will relate input trimming to the time transformation of interactive behaviors, as discussed in 
<em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">Why classic FRP does not fit interactive behavior</a></em>.
Also, how interactive FRP relates to <em><a href="http://conal.net/blog/posts/sequences-segments-and-signals/" title="blog post">Sequences, segments, and signals</a></em>.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=70&amp;md5=adc2fb47d1bda8d4267464ef19f66859"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/functional-interactive-behavior/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffunctional-interactive-behavior&amp;language=en_GB&amp;category=text&amp;title=Functional+interactive+behavior&amp;description=In+a+previous+post%2C+I+presented+a+fundamental+reason+why+classic+FRP+does+not+fit+interactive+behavior%2C+which+is+that+the+semantic+model+captures+only+the+influence+of+time+and...&amp;tags=comonad%2CFRP%2Cfunctional+reactive+programming%2Cinteraction%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Trimming inputs in functional reactive programming</title>
		<link>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming</link>
		<comments>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming#comments</comments>
		<pubDate>Wed, 10 Dec 2008 09:00:33 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[interaction]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=71</guid>
		<description><![CDATA[This post takes a close look at one awkward aspect of classic (non-arrow) FRP for interactive behavior, namely the need to trim (or &#8220;age&#8221;) old input. Failing to trim results in behavior that is incorrect and grossly inefficient. Behavior trimming connects directly into the comonad interface mentioned in a few recent posts, and is what [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Trimming inputs in functional reactive programming

Tags: FRP, functional reactive programming, interaction, comonad

URL: http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/

-->

<!-- references -->

<!-- teaser -->

<p>This post takes a close look at one awkward aspect of <em>classic</em> (non-arrow) FRP for interactive behavior, namely the need to <em>trim</em> (or &#8220;age&#8221;) old input.
Failing to trim results in behavior that is incorrect and grossly inefficient.</p>

<p>Behavior trimming connects directly into the <a href="http://conal.net/blog/tag/comonad/">comonad</a> interface mentioned in a few recent posts, and is what got me interested in comonads recently.</p>

<p>In absolute-time FRP, trimming has a purely operational significance.
Switching to relative time, trimming is recast as a semantically familiar operation, namely the generalized <code>drop</code> function used in two <a href="http://conal.net/blog/tag/segment/">recent posts</a>.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-71"></span></p>

<p>In the rest of this post, I&#8217;ll adopt two abbreviations, for succinctness:</p>

<pre><code>type B = Behavior
type E = Event
</code></pre>

<h3>Trimming inputs</h3>

<p>An awkward aspect of classic FRP has to do with switching phases of behavior.
Each phase is a function of some static (momentary) input and some dynamic (time-varying) input, e.g.,</p>

<pre><code>sleep :: B World -&gt; B Cat
eat   :: Appetite   -&gt; B World -&gt; B Cat
prowl :: Friskiness -&gt; B World -&gt; B Cat

wake   :: B World -&gt; E Friskiness
hunger :: B World -&gt; E Appetite
</code></pre>

<p>As a first try, our cat prowls upon waking and eats when hungry, taking into account its surrounding world:</p>

<pre><code>cat1 :: B World -&gt; B Cat
cat1 world = sleep world `switcher`
               ((flip prowl world &lt;$&gt; wake   world) `mappend`
                (flip eat   world &lt;$&gt; hunger world))
</code></pre>

<p>The <code>(&lt;$&gt;)</code> here, from <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html" title="Haskell module documentation">Control.Applicative</a>, is a synonym for <code>fmap</code>.
In this context,</p>

<pre><code>(&lt;$&gt;) :: (a -&gt; B Cat) -&gt; E a -&gt; E (B Cat)
</code></pre>

<p>The FRP <code>switcher</code> function switches to new behavior phases as they&#8217;re generated by an event, beginning with a given initial behavior:</p>

<pre><code>switcher :: B a -&gt; E (B a) -&gt; B a
</code></pre>

<p>And the <code>mappend</code> here merges two events into one, combining their occurrences.</p>

<p>When switching phases, we generally want the new phase to start responding to input exactly where the old phase left off.
If we&#8217;re not careful, however, the new phase will begin with an old input.
I&#8217;ve made exactly this mistake in defining <code>cat1</code> above.
Consequently, each new phase will begin by responding to all of the old input and then carry on.
This meaning is both unintended and is very expensive (the dreaded &#8220;space-time&#8221; leak).</p>

<p>This difficulty is not unique to FRP.
In functional programming, we have to be careful how we hold onto our inputs, so that they can get accessed and freed incrementally.
I don&#8217;t think the difficulty arises much in imperative programming, because input (like output) is destructively altered, and programs have access only to the current state.</p>

<p>I&#8217;ve done it wrong above, in defining <code>cat</code>.
How can I do it right?
The solution/hack I came up for Fran was to add a function that trims (&#8220;ages&#8221;) dynamic input while waiting for event occurrences.</p>

<pre><code>trim :: B b -&gt; E a -&gt; E (a, B b)
</code></pre>

<p><code>trim b e</code> follows <code>b</code> and <code>e</code> in parallel.
At each occurrence of <code>e</code>, the remainder of <code>b</code> is paired up with the event data from <code>e</code>.</p>

<p>Now I can define the interactive, multi-phase behavior I intend:</p>

<pre><code>cat2 :: B World -&gt; B Cat
cat2 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trim world (wake   world)) `mappend`
                (uncurry eat   &lt;$&gt; trim world (hunger world)))
</code></pre>

<p>The event <code>trim world (wake world)</code> occurs whenever <code>wake world</code> does, and has as event data the cat&#8217;s friskiness on waking, plus the remainder of the cat&#8217;s world at the occurrence time.
The &#8220;<code>uncurry prowl &lt;$&gt;</code>&#8221; applies <code>prowl</code> to each friskiness and remainder world on waking.
Similarly for the other phase.</p>

<p>I think this version defines the behavior I want and that it can run efficiently, assuming that <code>trim e b</code> traverses <code>e</code> and <code>b</code> in parallel (so that laziness doesn&#8217;t cause a space-time leak).
However, this definition is much trickier than what I&#8217;m looking for.</p>

<p>One small improvement is to abstract a trimming pattern:</p>

<pre><code>trimf :: (B i -&gt; E o) -&gt; (B i -&gt; E (o, B i))
trimf ef i = trim i (ef i)

cat3 :: B World -&gt; B Cat
cat3 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trimf wake   world) `mappend`
                (uncurry eat   &lt;$&gt; trimf hunger world))
</code></pre>

<h3>A comonad comes out of hiding</h3>

<p>The <code>trim</code> functions above look a lot like snapshotting of behaviors:</p>

<pre><code>snapshot  :: B b -&gt; E a -&gt; E (a,b)

snapshot_ :: B b -&gt; E a -&gt; E b
</code></pre>

<p>Indeed, the meanings of trimming and snapshotting are very alike.
They both involving following an event and a behavior in parallel.
At each event occurrence, <code>snapshot</code> takes the <em>value</em> of the behavior at the occurrence time, while <code>trim</code> takes the entire remainder from that time on.</p>

<p>Given this similarlity, can one be defined in terms of the other?
If we had a function to &#8220;extract&#8221; the first defined value of a behavior, we could define<code>snapshot</code> via <code>trim</code>.</p>

<pre><code>b `snapshot` e = fmap (second extract) (b `trim` e)

extract :: B a -&gt; a
</code></pre>

<p>We can also define <code>trim</code> via <code>snapshot</code>, if we have a way to get all trimmed versions of a behavior &#8212; to &#8220;duplicate&#8221; a one-level behavior into a two-level behavior:</p>

<pre><code>b `trim` e = duplicate b `snapshot` e

duplicate :: B a -&gt; B (B a)
</code></pre>

<p>If you&#8217;ve run into comonads, you may recognize <code>extract</code> and <code>duplicate</code> as the operations of <code>Comonad</code>, dual to <code>Monad</code>&#8216;s <code>return</code> and <code>join</code>.
It was this definition of <code>trim</code> that got me interested in comonads recently.</p>

<p>In the style of <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em>,</p>

<pre><code>snapshot = (result.result.fmap.second) extract trim
</code></pre>

<p>or</p>

<pre><code>trim = argument remainders R.snapshot
</code></pre>

<p>The <code>extract</code> function is problematic for classic FRP, which uses absolute (global) time.
We don&#8217;t know with which time to sample the behavior.
With <em>relative-time FRP</em>, we&#8217;ll only ever sample at (local) time 0.</p>

<h3>Relative time</h3>

<p>So far, the necessary trimming has strong operational significance: it prevents obsolete reactions and the consequent space-time leaks.</p>

<p>If we switch from absolute time to relative time, then trimming becomes something with familiar semantics, namely <code>drop</code>, as generalized and used in two of my previous posts, <em><a href="http://conal.net/blog/posts/sequences-functions-and-segments/" title="blog post">Sequences, streams, and segments</a></em> and <em><a href="http://conal.net/blog/posts/sequences-segments-and-signals/" title="blog post">Sequences, segments, and signals</a></em>.</p>

<p>The semantic difference: trimming (absolute time) erases early content in an input; while dropping (relative time) shifts input backward in time, losing the early content in the same way as <code>drop</code> on sequences.</p>

<h3>What&#8217;s next?</h3>

<p>While input trimming can be managed systematically, doing so explicitly is tedious and error prone.
A follow-up post will automatically apply the techniques from this post.
Hiding and automating the mechanics of trimming allows interactive behavior to be expressed correctly and without distraction.</p>

<p>Another post will relate input trimming to the time transformation of interactive behaviors, as discussed in 
<em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">Why classic FRP does not fit interactive behavior</a></em>.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=71&amp;md5=842949917d89f4d726e5c20b26d662bc"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ftrimming-inputs-in-functional-reactive-programming&amp;language=en_GB&amp;category=text&amp;title=Trimming+inputs+in+functional+reactive+programming&amp;description=This+post+takes+a+close+look+at+one+awkward+aspect+of+classic+%28non-arrow%29+FRP+for+interactive+behavior%2C+namely+the+need+to+trim+%28or+%26%238220%3Bage%26%238221%3B%29+old+input.+Failing+to+trim+results...&amp;tags=comonad%2CFRP%2Cfunctional+reactive+programming%2Cinteraction%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Sequences, segments, and signals</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals</link>
		<comments>http://conal.net/blog/posts/sequences-segments-and-signals#comments</comments>
		<pubDate>Fri, 05 Dec 2008 08:14:33 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[monoid]]></category>
		<category><![CDATA[segment]]></category>
		<category><![CDATA[sequence]]></category>
		<category><![CDATA[type class morphism]]></category>
		<category><![CDATA[zipper]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=67</guid>
		<description><![CDATA[The post Sequences, streams, and segments offered an answer to the the question of what&#8217;s missing in the following box: infinitefinite discreteStream Sequence continuousFunction ??? I presented a simple type of function segments, whose representation contains a length (duration) and a function. This type implements most of the usual classes: Monoid, Functor, Zip, and Applicative, [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Sequences, segments, and signals

Tags: function, sequence, monoid, functor, applicative functor, comonad, FRP, functional reactive programming, segment, type class morphism, zipper

URL: http://conal.net/blog/posts/sequences-segments-and-signals/

-->

<!-- references -->

<!-- teaser -->

<p>The post <em><a href="http://conal.net/blog/posts/sequences-streams-and-segments/" title="blog post">Sequences, streams, and segments</a></em> offered an answer to the the question of what&#8217;s missing in the following box:</p>

<div align=center style="margin-bottom:10px">
  <table border="2">
    <tr><td></td><td style="text-align:center;padding:5px"><strong>infinite</strong><td style="text-align:center;padding:5px"><strong>finite</strong></third></tr>
    <tr><td style="text-align:center;padding:5px"><strong>discrete</strong><td style="text-align:center;padding:7px">Stream</td> <td style="text-align:center;padding:7px">Sequence</td></tr>
    <tr><td style="text-align:center;padding:5px"><strong>continuous</strong><td style="text-align:center;padding:7px">Function</td> <td style="text-align:center;padding:7px"><em>???</em></td></tr>
  </table>
</div>

<p>I presented a simple type of <em>function segments</em>, whose representation contains a length (duration) and a function.
This type implements most of the usual classes: <code>Monoid</code>, <code>Functor</code>, <code>Zip</code>, and <code>Applicative</code>, as well <code>Comonad</code>, but not <code>Monad</code>.
It also implements a new type class, <code>Segment</code>, which generalizes the list functions <code>length</code>, <code>take</code>, and <code>drop</code>.</p>

<p>The function type is simple and useful in itself.
I believe it can also serve as a semantic foundation for functional reactive programming (FRP), as I&#8217;ll explain in another post.
However, the type has a serious performance problem that makes it impractical for some purposes, including as implementation of FRP.</p>

<p>Fortunately, we can solve the performance problem by adding a simple layer on top of function segments, to get what I&#8217;ll call &#8220;signals&#8221;.
With this new layer, we have an efficient replacement for function segments that implements exactly the same interface with exactly the same semantics.
Pleasantly, the class instances are defined fairly simply in terms of the corresponding instances on function segments.</p>

<p>You can download the <a href="http://conal.net/blog/code/Signal.hs">code for this post</a>.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-12-06: <code>dup [] = []</code> near the end (was <code>[mempty]</code>).</li>
<li>2008-12-09: Fixed <code>take</code> and <code>drop</code> default definitions (thanks to sclv) and added point-free variant.</li>
<li>2008-12-18: Fixed <code>appl</code>, thanks to sclv.</li>
<li>2011-08-18: Eliminated accidental emoticon in the definition of <code>dup</code>, thanks to anonymous.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-67"></span></p>

<h3>The problem with function segments</h3>

<p>The type of function segments is defined as follows:</p>

<pre><code>data t :-&gt;# a = FS t (t -&gt; a)
</code></pre>

<p>The domain of the function segment is from zero up to but not including the given length.</p>

<p>An efficiency problem becomes apparent when we look at the <code>Monoid</code> instance:</p>

<pre><code>instance (Ord t, Num t) =&gt; Monoid (t :-&gt;# a) where
    mempty = FS 0 (error "sampling empty 't :-&gt;# a'")
    FS c f `mappend` FS d g =
      FS (c + d) ( t -&gt; if t &lt;= c then f t else g (t - c))
</code></pre>

<p>Concatenation (<code>mappend</code>) creates a new segment that chooses, for every domain value <code>t</code>, whether to use one function or another.
If the second, then <code>t</code> must be shifted backward, since the function is being shifted forward.</p>

<p>This implementation would be fine if we use <code>mappend</code> just on simple segments.
Once we get started, however, we&#8217;ll want to concatenate lots &amp; lots of segments.
In FRP, time-varying values go through many phases (segments) as time progresses.
Each quantity is described by a single &#8220;behavior&#8221; (sometimes called a &#8220;signal&#8221;) with many, and often infinitely many, phases.
Imagine an infinite tree of concatenations, which is typical for FRP behaviors.
At every moment, one phase is active.
Every sampling must recursively discover the active phase and the accumulated domain translation (from successive subtractions) to apply when sampling that phase.
Quite commonly, concatenation trees get progressively deeper on the right (larger <code>t</code> values).
In that case, sampling will get slower and slower with time.</p>

<p>I like to refer to these progressive slow-downs as &#8220;time leaks&#8221;.
There is also a serious space leak, since all of the durations and functions that go into a composed segment will be retained.</p>

<h3>Sequences of segments</h3>

<p>The problem above can be solved with a simple representation change.
Instead of combining functions into functions, just keep a list of simple function segments.</p>

<pre><code>-- | Signal indexed by t with values of type a.
newtype t :-&gt; a = S { unS :: [t :-&gt;# a] }
</code></pre>

<p>I&#8217;ll restrict in function segments to be <em>non-empty</em>, to keep the rest of the implementation simple and efficient.</p>

<p>This new representation allows for efficient <em>monotonic</em> sampling of signals.
As old segments are passed up, they can be dropped.</p>

<h4>What does it mean?</h4>

<p>There&#8217;s one central question for me in defining any data type: <em>What does it mean?</em></p>

<p>The meaning I&#8217;ll take for signals is function segments.
This interpretation is made precise in a function that maps from the type to the model (meaning).
In this case, simply concatenate all of the function segments:</p>

<pre><code>meaning :: (Ord t, Num t) =&gt; (t :-&gt; a) -&gt; (t :-&gt;# a)
meaning = mconcat . unS
</code></pre>

<p>Specifying the meaning of a type gives users a working model, and it defines correctness of implementation.
It also tells me what class instances to implement and tells users what instances to expect.
If a type&#8217;s meaning implements a class then I want the type to as well.
Moreover, the type&#8217;s intances have to agree with the model&#8217;s instances.
I&#8217;ve described this latter principle in <em><a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Simplifying semantics with type class morphisms</a></em> and <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">some other posts</a>.</p>

<h4>Higher-order wrappers</h4>

<p>To keep the code below short and clear, I&#8217;ll use some functions for adding and removing the newtype wrappers.
These higher-order function apply functions inside of <code>(:-&gt;)</code> representations:</p>

<pre><code>inS  :: ([s :-&gt;# a] -&gt; [t :-&gt;# b])
     -&gt; ((s :-&gt;  a) -&gt; (t :-&gt;  b))

inS2 :: ([s :-&gt;# a] -&gt; [t :-&gt;# b] -&gt; [u :-&gt;# c])
     -&gt; ((s :-&gt;  a) -&gt; (t :-&gt;  b) -&gt; (u :-&gt;  c))
</code></pre>

<p>Using the trick described in <em><a href="http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/" title="blog post">Prettier functions for wrapping and wrapping</a></em>, the definitions are simpler than the types:</p>

<pre><code>inS  = result   S . argument unS
inS2 = result inS . argument unS
</code></pre>

<h4><code>Functor</code></h4>

<p>The <code>Functor</code> instance applies a given function inside the function segments inside the lists:</p>

<pre><code>instance Functor ((:-&gt;) t) where
    fmap h (S ss) = S (fmap (fmap h) ss)
</code></pre>

<p>Or, in the style of <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em>,</p>

<pre><code>instance Functor ((:-&gt;) t) where
    fmap = inS . fmap . fmap
</code></pre>

<p>Why this definition?
Because it is correct with respect to the semantic model, i.e., the meaning of <code>fmap</code> is <code>fmap</code> of the meaning, i.e.,</p>

<pre><code> meaning . fmap h == fmap h . meaning
</code></pre>

<p>which is to say that the following diagram commutes:</p>

<div align=center><img src="http://conal.net/blog/pictures/signal-meaning-fmap-morphism.png"/></div>

<p>Proof:</p>

<pre><code>meaning . fmap h 

  == {- fmap definition -}

meaning . S . fmap (fmap h) . unS

  == {- meaning definition -}

mconcat . unS . S . fmap (fmap h) . unS

  == {- unS and S are inverses  -}

mconcat . fmap (fmap h) . unS

  == {- fmap h distributes over mappend -}

fmap h . mconcat . unS

  == {- meaning definition -}

fmap . meaning
</code></pre>

<h4><code>Applicative</code> and <code>Zip</code></h4>

<p>Again, the <code>meaning</code> functions tells us what the <code>Applicative</code> instance has to mean.
We only get to choose how to implement that meaning correctly.
The <code>Applicative</code> <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">morphism properties</a>:</p>

<pre><code>meaning (pure a)    == pure a
meaning (bf &lt;*&gt; bx) == meaning bf &lt;*&gt; meaning bx
</code></pre>

<p>Our <code>Applicative</code> instance has a definition similar in simplicity and style to the <code>Functor</code> instance, assuming a worker function <code>appl</code> for <code>(&lt;*&gt;)</code>:</p>

<pre><code>instance (Ord t, Num t, Bounded t) =&gt; Applicative ((:-&gt;) t) where
    pure  = S . pure . pure
    (&lt;*&gt;) = inS2 appl

appl :: (Ord t, Num t, Bounded t) =&gt;
        [t :-&gt;# (a -&gt; b)] -&gt; [t :-&gt;# a] -&gt; [t :-&gt;# b]
</code></pre>

<p>This worker function is somewhat intricate.
At least my implementation of it is, and perhaps there&#8217;s a simpler one.</p>

<p>Again, the <code>meaning</code> functions tells us what the <code>Applicative</code> instance has to mean.
We only get to choose how to implement that meaning correctly.</p>

<p>First, if either segment list runs out, the combination runs out (because the same is true for the <em>meaning</em> of signals).</p>

<pre><code>[] `appl` _  = []

_  `appl` [] = []
</code></pre>

<p>If neither segment list is empty, open up the first segment.
Split the longer segment into a prefix that matches the shorter segment, and combine the two segments with <code>(&lt;*&gt;)</code> (on function segments).
Toss the left-over piece back in its list, and continue.</p>

<pre><code>(fs:fss') `appl` (xs:xss')
   | fd == xd  = (fs  &lt;*&gt; xs ) : (fss' `appl`       xss' )
   | fd &lt;  xd  = (fs  &lt;*&gt; xs') : (fss' `appl` (xs'':xss'))
   | otherwise = (fs' &lt;*&gt; xs ) : ((fs'':fss') `appl` xss')
 where
   fd         = length fs
   xd         = length xs
   (fs',fs'') = splitAt xd fs
   (xs',xs'') = splitAt fd xs
</code></pre>

<p>A <code>Zip</code> instance is easy as always with applicative functors:</p>

<pre><code>instance (Ord t, Num t, Bounded t) =&gt; Zip ((:-&gt;) t) where zip = liftA2 (,)
</code></pre>

<h4><code>Monoid</code></h4>

<p>The <code>Monoid</code> instance:</p>

<pre><code>instance Monoid (t :-&gt; a) where
  mempty = S []
  S xss `mappend` S yss = S (xss ++ yss)
</code></pre>

<p>Correctness follows from properties of <code>mconcat</code> (as used in the <code>meaning</code> function).</p>

<p>We&#8217;re really just using the <code>Monoid</code> instance for the underlying representation, i.e.,</p>

<pre><code>instance Monoid (t :-&gt; a) where
    mempty  = S mempty
    mappend = inS2 mappend
</code></pre>

<h4><code>Segment</code></h4>

<p>The <code>Segment</code> class has <code>length</code>, <code>take</code> and <code>drop</code>.
It&#8217;s handy to include also <code>null</code> and <code>splitAt</code>, both modeled after their counterparts on lists.</p>

<p>The new &amp; improved <code>Segment</code> class:</p>

<pre><code>class Segment seg dur | seg -&gt; dur where
    null    :: seg -&gt; Bool
    length  :: seg -&gt; dur
    take    :: dur -&gt; seg -&gt; seg
    drop    :: dur -&gt; seg -&gt; seg
    splitAt :: dur -&gt; seg -&gt; (seg,seg)
    -- Defaults:
    splitAt d s = (take d s, drop d s)
    take    d s = fst (splitAt d s)
    drop    d s = snd (splitAt d s)
</code></pre>

<p>If we wanted to require <code>dur</code> to be numeric, we could add a default for <code>null</code> as well.
This default could be quite expensive in some cases.
(In the style of <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em>, <code>take = (result.result) fst splitAt</code>, and similarly for <code>drop</code>.)</p>

<p>The <code>null</code> and <code>length</code> definitions are simple, following from to properties of <code>mconcat</code>.</p>

<pre><code>instance (Ord t, Num t) =&gt; Segment (t :-&gt; a) t where
  null   (S xss) = null xss
  length (S xss) = sum (length &lt;$&gt; xss)
  ...
</code></pre>

<p>The null case says that the signal is empty exactly when there are no function segments.
This simple definition relies on our restriction to non-empty function segments.
If we drop that restriction, we&#8217;d have to check that every segment is empty:</p>

<pre><code>  -- Alternative definition
  null (S xss) = all null xss
</code></pre>

<p>The <code>length</code> is just the sum of the lengths.</p>

<p>The tricky piece is <code>splitAt</code> (used to define both <code>take</code> and drop), which must assemble segments to satisfy the requested prefix length.
The last segment used might have to get split into two, with one part going into the prefix and one to the suffix.</p>

<pre><code>  splitAt _ (S [])  = (mempty,mempty)
  splitAt d b | d &lt;= 0 = (mempty, b)
  splitAt d (S (xs:xss')) =
    case (d `compare` xd) of
      EQ -&gt; (S [xs], S xss')
      LT -&gt; let (xs',xs'') = splitAt d xs in
              (S [xs'], S (xs'':xss'))
      GT -&gt; let (S uss, suffix) = splitAt (d-xd) (S xss') in
              (S (xs:uss), suffix)
   where
     xd = length xs
</code></pre>

<h4><code>Copointed</code> and <code>Comonad</code></h4>

<p>To extract an element from a signal, extract an element from its first function segment.
Awkwardly, extraction will fail (produce &perp;/error) when the signal is empty.</p>

<pre><code>instance Num t =&gt; Copointed ((:-&gt;) t) where
    extract (S [])     = error "extract: empty S"
    extract (S (xs:_)) = extract xs
</code></pre>

<p>I&#8217;ve exploited our restriction to non-empty function segments.
Otherwise, <code>extract</code> would have to skip past the empty ones:</p>

<pre><code>-- Alternative definition
instance Num t =&gt; Copointed ((:-&gt;) t) where
    extract (S []) = error "extract: empty S"
    extract (S (xs:xss'))
      | null xs     = extract (S xss')
      | otherwise   = extract xs
</code></pre>

<p>The error/&perp; in this definition is dicey, as is the one for function segments.
If we allow the same abuse in order to define a list <code>Copointed</code>, we can get an alternative to the first definition that is prettier but gives a less helpful error message:</p>

<pre><code>instance Num t =&gt; Copointed ((:-&gt;) t) where
    extract = extract . extract . unS
</code></pre>

<p>See the closing remarks for more about this diciness.</p>

<p>Finally, we have <code>Comonad</code>, with its <code>duplicate</code> method.</p>

<pre><code>duplicate :: (t :-&gt; a) -&gt; (t :-&gt; (t :-&gt; a))
</code></pre>

<p>I get confused with wrapping and unwrapping, so let&#8217;s separate the definition into a packaging part and a content part.</p>

<pre><code>instance (Ord t, Num t) =&gt; Comonad ((:-&gt;) t) where
    duplicate = fmap S . inS dup
</code></pre>

<p>with content part:</p>

<pre><code>dup :: (Ord t, Num t) =&gt; [t :-&gt;# a] -&gt; [t :-&gt;# [t :-&gt;# a]]
</code></pre>

<p><!-- 
I think of `duplicate` as forming all of the *tails* of a segment (as it does with lists via the standard `tails` function). 
-->
The helper function, <code>dup</code>, takes each function segment and prepends each of its tails onto the remaining list of segments.</p>

<p>If the segment list is empty, then it has only one tail, also empty.</p>

<pre><code>dup []        = []

dup (xs:xss') = ((: xss') &lt;$&gt; duplicate xs) : dup xss'
</code></pre>

<h3>Closing remarks</h3>

<ul>
<li><p>The definitions above use the function segment type only through its type class interfaces, and so can all of them can be generalized.
Several definitions rely on the <code>Segment</code> instance, but otherwise, each method for the composite type relies on the corresponding method for the underlying segment type.
(For instance, <code>fmap</code> uses <code>fmap</code>, <code>(&lt;*&gt;)</code> uses <code>(&lt;*&gt;)</code>, <code>Segment</code> uses <code>Segment</code>, etc.)
This generality lets us replace function segments with more efficient representations, e.g., doing constant propagation, as in <a href="http://haskell.org/haskellwiki/Reactive" title="Wiki page for the Reactive library">Reactive</a>.
We can also generalize from lists in the definitions above.</p></li>
<li><p>Even without concatenation, function segments can become expensive when <code>drop</code> is repeatedly applied, because function shifts accumulate (e.g., <code>f . (+ 0.01) . (+ 0.01) ....</code>).
A more <code>drop</code>-friendly representation for function segments would be a function and an offset.
Successive drops would add offsets, and <code>extract</code> would always apply the function to its offset.
This representation is similar to the <code>FunArg</code> comonad, mentioned in <a href="http://cs.ioc.ee/~tarmo/papers/essence.pdf" title="Paper by Tarmo Uustalu and Varmo Vene">The Essence of Dataflow Programming</a> (Section 5.2).</p></li>
<li><p>The list-of-segments representation enables efficient monotonic sampling, simply by dropping after each sample.
A variation is to use a list zipper instead of a list.
Then non-monotonic sampling will be efficient as long as successive samplings are for nearby domain values.
Switching to multi-directional representation would lose the space efficiency of unidirectional representations.
The latter work well with lazy evaluation, often running in constant space, because old values are recycled while new values are getting evaluated.</p></li>
<li><p>Still another variation is to use a binary tree instead of a list, to avoid the list append in the <code>Monoid</code> instance for <code>(t :-&gt; a)</code>.
A tree zipper would allow non-monotonic sampling.
Sufficient care in data structure design could perhaps yield efficient random access.</p></li>
<li><p>There&#8217;s a tension between the <code>Copointed</code> and <code>Monoid</code> interfaces.
<code>Copointed</code> has <code>extract</code>, and <code>Monoid</code> has <code>mempty</code>, so what is the value of <code>extract mempty</code>?
Given that <code>Copointed</code> is parameterized over <em>arbitrary</em> types, the only possible answer seems to be &perp; (as in the use of <code>error</code> above).
I don&#8217;t know if the comonad laws can all hold for possibly-empty function segments or for possibly-empty signals.
I&#8217;m grateful to <a href="http://comonad.com/reader/">Edward Kmett</a> for helping me understand this conflict.
He suggested using two coordinated types, one possibly-empty (a monoid) and the other non-empty (a comonad).
I&#8217;m curious to see whether that idea works out.</p></li>
</ul>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=67&amp;md5=e15e8c9dfd9e8f9c0aadd8dc805515dc"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/sequences-segments-and-signals/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fsequences-segments-and-signals&amp;language=en_GB&amp;category=text&amp;title=Sequences%2C+segments%2C+and+signals&amp;description=The+post+Sequences%2C+streams%2C+and+segments+offered+an+answer+to+the+the+question+of+what%26%238217%3Bs+missing+in+the+following+box%3A+infinitefinite+discreteStream+Sequence+continuousFunction+%3F%3F%3F+I+presented+a+simple+type...&amp;tags=applicative+functor%2Ccomonad%2CFRP%2Cfunction%2Cfunctional+reactive+programming%2Cfunctor%2Cmonoid%2Csegment%2Csequence%2Ctype+class+morphism%2Czipper%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Sequences, streams, and segments</title>
		<link>http://conal.net/blog/posts/sequences-streams-and-segments</link>
		<comments>http://conal.net/blog/posts/sequences-streams-and-segments#comments</comments>
		<pubDate>Mon, 01 Dec 2008 07:29:27 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[monoid]]></category>
		<category><![CDATA[sequence]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=65</guid>
		<description><![CDATA[What kind of thing is a movie? Or a song? Or a trajectory from point A to point B? If you&#8217;re a computer programmer/programmee, you might say that such things are sequences of values (frames, audio samples, or spatial locations). I&#8217;d suggest that these discrete sequences are representations of something more essential, namely a flow [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Sequences, streams, and segments

Tags: function, sequence, monoid, functor, applicative functor, comonad, FRP, functional reactive programming, segment

URL: http://conal.net/blog/posts/sequences-functions-and-segments/

-->

<!-- references -->

<!-- teaser -->

<p>What kind of thing is a movie?
Or a song?
Or a trajectory from point A to point B?
If you&#8217;re a computer programmer/programmee, you might say that such things are sequences of values (frames, audio samples, or spatial locations).
I&#8217;d suggest that these discrete sequences are representations of something more essential, namely a <em>flow</em> of continuously time-varying values.
Continuous models, whether in time or space, are often more compact, precise, adaptive, and composable than their discrete counterparts.</p>

<p>Functional programming offers great support for sequences of variable length.
<em>Lazy</em> functional programming adds <em>infinite</em> sequences, often called <em>streams</em>, which allows for more elegant and modular programming.</p>

<p>Functional programming also has functions as first class values, and when the function&#8217;s domain is (conceptually) continuous, we get a continuous counterpart to infinite streams.</p>

<p>Streams, sequences, and functions are three corners of a square.
Streams are discrete and infinite, sequences are discrete and finite, and functions-on-reals are continuous and infinite.
The missing corner is continuous and finite, and that corner is the topic of this post.</p>

<div align=center>
  <table border="2">
    <tr><td></td><td style="text-align:center;padding:5px"><strong>infinite</strong><td style="text-align:center;padding:5px"><strong>finite</strong></third></tr>
    <tr><td style="text-align:center;padding:5px"><strong>discrete</strong><td style="text-align:center;padding:15px">Stream</td> <td style="text-align:center;padding:15px">Sequence</td></tr>
    <tr><td style="text-align:center;padding:5px"><strong>continuous</strong><td style="text-align:center;padding:15px">Function</td> <td style="text-align:center;padding:15px"><em>???</em></td></tr>
  </table>
</div>

<p>You can download the <a href="http://conal.net/blog/code/Segment.hs">code for this post</a>.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-12-01: Added <a href="http://conal.net/blog/code/Segment.hs">Segment.hs</a> link.</li>
<li>2008-12-01: Added <code>Monoid</code> instance for function segments.</li>
<li>2008-12-01: Renamed constructor &#8220;<code>DF</code>&#8221; to &#8220;<code>FS</code>&#8221; (for &#8220;function segment&#8221;)</li>
<li>2008-12-05: Tweaked the inequality in <code>mappend</code> on <code>(t :-&gt;# a)</code>. </li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-65"></span></p>

<!--
This play has a cast of characters you may have met before.
`Monoid` is the star of the show, with `Functor` and `Applicative` playing supporting roles.
`Monad` appears only briefly.
Making her debut appearance on this blog is `Comonad`.
We'll be seeing more of her in future episodes.
-->

<h3>Streams</h3>

<p>I&#8217;ll be using Wouter Swierstra&#8217;s <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream" title="Haskell library on Hackage">Stream library</a>.
A stream is an infinite sequence of values:</p>

<pre><code>data Stream a = Cons a (Stream a)
</code></pre>

<!--, but renaming his `Cons` constructor to `(:<)`, as used in *[The Essence of Dataflow Programming][]*. -->

<p><code>Stream</code> is a functor and an applicative functor.</p>

<pre><code>instance Functor Stream where
    fmap f (Cons x xs) = Cons (f x) (fmap f xs)

instance Applicative Stream where
    pure  = repeat
    (&lt;*&gt;) = zipWith ($)

repeat :: a -&gt; Stream a
repeat x = Cons x (repeat x)
</code></pre>

<h3>Comonads</h3>

<p>Recently I&#8217;ve gotten enamored with comonads, which are dual to monads.
In other words, comonads are like monads but wearing their category arrows backwards.
I&#8217;ll be using the comonad definitions from the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/category-extras" title="Haskell library on Hackage">category-extras library</a>.</p>

<p>The most helpful intuitive description I&#8217;ve found is that comonads describe <em>values in context</em>.</p>

<p>The <code>return</code> method injects a pure value into a monadic value (having no effect).</p>

<pre><code>return  :: Monad m     =&gt; a -&gt; m a
</code></pre>

<p>The dual to monadic <code>return</code> is <code>extract</code> (sometimes called &#8220;<code>counit</code>&#8221; or &#8220;<code>coreturn</code>&#8220;), which extracts a value out of a comonadic value (discarding the value&#8217;s context).
<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/category-extras" title="Haskell library on Hackage">category-extras library</a> splites this method out from <code>Comonad</code> into the <code>Copointed</code> class:</p>

<pre><code>extract :: Copointed w =&gt; w a -&gt; a
</code></pre>

<p>Monadic values are typically <em>produced</em> in effectful computations:</p>

<pre><code>a -&gt; m b
</code></pre>

<p>Comonadic values are typically <em>consumed</em> in context-sensitive computations:</p>

<pre><code>w a -&gt; b
</code></pre>

<p>(Kleisli arrows wrap the producer pattern, while CoKleisli arrows wrap the consumer pattern.)</p>

<p>Monads have a way to extend a monadic producer into one that consumes to an entire monadic value:</p>

<pre><code>(=&lt;&lt;) :: (Monad m) =&gt; (a -&gt; m b) -&gt; (m a -&gt; m b)
</code></pre>

<p>We more often see this operation in its flipped form (obscuring the conceptual distinction between Haskell arrows and arbitrary category arrows):</p>

<pre><code>(&gt;&gt;=) :: (Monad m) =&gt; m a -&gt; (a -&gt; m b) -&gt; m b
</code></pre>

<p>Dually, comonads have a way to extend a comonadic consumer into one that produces an entire comonadic value:</p>

<pre><code>extend :: (Comonad w) =&gt; (w a -&gt; b) -&gt; (w a -&gt; w b)
</code></pre>

<p>which also has a flipped version:</p>

<pre><code>(=&gt;&gt;) :: (Comonad w) =&gt; w a -&gt; (w a -&gt; b) -&gt; w b
</code></pre>

<p>Another view on monads is as having a way to <code>join</code> two monadic levels into one.</p>

<pre><code>join      :: (Monad   m) =&gt; m (m a) -&gt; m a
</code></pre>

<p>Dually, comonads have a way to <code>duplicate</code> one level into two:</p>

<pre><code>duplicate :: (Comonad w) =&gt; w a -&gt; w (w a)
</code></pre>

<p>For a monad, any of <code>join</code>, <code>(=&lt;&lt;)</code>, and <code>(&gt;&gt;=)</code> can be used to define the others.
For a comonad, any of <code>duplicate</code>, <code>extend</code>, and <code>(=&gt;&gt;)</code> can be used to define the others.</p>

<h3>The Stream comonad</h3>

<p>What might the stream comonad be?</p>

<p>The Stream library already has functions of the necessary types for <code>extract</code> and <code>duplicate</code>, corresponding to familiar list functions:</p>

<pre><code>head :: Stream a -&gt; a
head (Cons x _ ) = x

tails :: Stream a -&gt; Stream (Stream a)
tails xs = Cons xs (tails (tail xs))
</code></pre>

<p>where</p>

<pre><code>tail :: Stream a -&gt; Stream a
tail (Cons _ xs) = xs
</code></pre>

<p>Indeed, <code>head</code> and <code>tails</code> are just what we&#8217;re looking for.</p>

<pre><code>instance Copointed Stream where extract   = head
instance Comonad   Stream where duplicate = tails
</code></pre>

<p>There is also a <code>Monad</code> instance for <code>Stream</code>, in which <code>return</code> is <code>repeat</code> (matching <code>pure</code> as expected) and <code>join</code> is diagonalization, producing a stream whose <em>n<sup>th</sup></em> element is the <em>n<sup>th</sup></em> element of the <em>n<sup>th</sup></em> element of a given stream of streams.</p>

<div class="exercise">

<p><strong>Exercise</strong>: The indexing function <code>(!!)</code> is a sort of semantic function for <code>Stream</code>.
Show that <code>(!!)</code> is a morphism for <code>Functor</code>, <code>Applicative</code>, <code>Monad</code>, and <code>Comonad</code>.
In other words, the meaning of the functor is the functor of the meanings, and similarly for the other type classes.
The <code>Comonad</code> case has a little wrinkle.
See the posts on <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on morphisms">type class morphisms</a>.</p>

</div>

<h3>Adding finiteness</h3>

<p>Lists and other possibly-finite sequence types add an interesting new aspect over streams, which is concatenation, usually wrapped in a <code>Monoid</code> instance.</p>

<pre><code>class Monoid o where
    mempty  :: o
    mappend :: o -&gt; o -&gt; o
</code></pre>

<p>Lists also have <code>take</code> and <code>drop</code> operations, which can undo the effect of concatenation, as well as a notion of <code>length</code> (duration).
Let&#8217;s generalize these three to be methods of a new type class, <code>Segment</code>, so that we can defined <em>continuous</em> versions.</p>

<pre><code>class Segment seg len where
    length :: seg -&gt; len
    drop   :: len -&gt; seg -&gt; seg
    take   :: len -&gt; seg -&gt; seg
</code></pre>

<p>For lists, we can use the prelude functions</p>

<pre><code>instance Segment [a] Int where
    length = Prelude.length
    drop   = Prelude.drop
    take   = Prelude.take
</code></pre>

<p>Or the more <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#26">generic versions</a>:</p>

<pre><code>instance Integral i =&gt; Segment [a] i where
    length = genericLength
    drop   = genericDrop
    take   = genericTake
</code></pre>

<p>These three functions relate to <code>mappend</code>, to give us the following &#8220;Segment laws&#8221;:</p>

<pre><code>drop (length as) (as `mappend` bs) == bs
take (length as) (as `mappend` bs) == as

t &lt;= length as ==&gt; length (take t as) == t
t &lt;= length as ==&gt; length (drop t as) == length as - t
</code></pre>

<h3 id="adding-continuity">Adding continuity</h3>

<p>Streams and lists are <em>discrete</em>, containing countably many or finitely many elements.
They both have <em>continuous</em> counterparts.</p>

<p>When we think of a stream as a function from natural numbers, then John Reynolds&#8217;s alternative arises: functions over <em>real numbers</em>, i.e., a continuum of values.
If we want uni-directional streams, then stick with non-negative reals.</p>

<p>Many stream and list operations are meaningful and useful not only for discrete sequences but also for their continuous counterparts.</p>

<p>The infinite (stream-like) case is already handled by the class instances for functions found in the GHC base libraries (<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Functor-Instances.html" title="Haskell module documentation">Control.Functor.Instances</a> and <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html" title="Haskell module documentation">Control.Applicative</a>).</p>

<pre><code>instance Functor ((-&gt;) t) where
    fmap = (.)

instance Applicative ((-&gt;) t) where
    pure = const
    (f &lt;*&gt; g) x = (f x) (g x)

instance Monad ((-&gt;) t) where
    return = const
    f &gt;&gt;= k =  t -&gt; k (f t) t
</code></pre>

<p>As a consequence,</p>

<pre><code>  join f == f &gt;&gt;= id ==  t -&gt; f t t
</code></pre>

<p>Assume a type wrapper, <code>NonNeg</code>, for non-negative values.
For discrete streams, <code>r == NonNeg Integer</code>, while for continuous streams, <code>r == NonNeg R</code>, for some type <code>R</code> representing reals.</p>

<p>The <a href="http://hackage.haskell.org/packages/archive/category-extras/latest/doc/html/Control-Comonad.html">co-monadic instances</a> from the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/category-extras" title="Haskell library on Hackage">category-extras library</a>:</p>

<pre><code>instance Monoid o =&gt; Copointed ((-&gt;) o) where
    extract f = f mempty

instance Monoid o =&gt; Comonad ((-&gt;) o) where
    duplicate f x =  y -&gt; f (x `mappend` y)
</code></pre>

<h3>Finite and continuous</h3>

<p>Functions provide a setting for generalized streams.
How do we add finiteness?
A very simple answer is to combine a length (duration) with a function, to form a &#8220;function segment&#8221;:</p>

<pre><code>data t :-&gt;# a = FS t (t -&gt; a)
</code></pre>

<p>The domain of this function is from zero to just short of the given length.</p>

<p>Now let&#8217;s define class instances.</p>

<p><strong>Exercise</strong>: Show that all of the instances below are semantically consistent with the <code>Stream</code> and <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t%3AZipList"><code>ZipList</code></a> instances.</p>

<h4><code>Monoid</code></h4>

<p>Empty function segments have zero duration.
Concatenation adds durations and samples either function, right-shifting the second one.</p>

<pre><code>instance (Ord t, Num t) =&gt; Monoid (t :-&gt;# a) where
    mempty = FS 0 (error "sampling empty 't :-&gt;# a'")
    FS c f `mappend` FS d g =
      FS (c + d) ( t -&gt; if t &lt;= c then f t else g (t - c))
</code></pre>

<h4><code>Segment</code></h4>

<p>The <code>Segment</code> operations are easy to define:</p>

<pre><code>instance Num t =&gt; Segment (t :-&gt;# a) t where
    length (FS d _) = d
    drop t (FS d f) = FS (d - t) ( t' -&gt; f (t + t'))
    take t (FS _ f) = FS t f
</code></pre>

<p>Notice what&#8217;s going on with <code>drop</code>.
The length gets shortened by <code>t</code> (the amount dropped), and the function gets shifted (to the &#8220;left&#8221;) by <code>t</code>.</p>

<p>There&#8217;s also a tantalizing resemblance between this <code>drop</code> definition and <code>duplicate</code> for the function comonad.
We&#8217;ll return in another post to tease out this and</p>

<p>I&#8217;ve allowed dropping or taking more than is present, though these cases can be handled with an error or a by taking or dropping fewer elements (as with the list <code>drop</code> and <code>take</code> functions).</p>

<h4><code>Functor</code>, <code>Zip</code> and <code>Applicative</code></h4>

<p><code>fmap</code> applies a given function to each of the function values, leaving the length unchanged.</p>

<pre><code>instance Functor ((:-&gt;#) t) where
    fmap h (FS d f) = FS d (h . f)
</code></pre>

<p><code>zip</code> pairs corresponding segment values and runs out with the shorter segment.
(See <em><a href="http://conal.net/blog/posts/more-beautiful-fold-zipping" title="blog post">More beautiful fold zipping</a></em> for the <code>Zip</code> class.)</p>

<pre><code>instance Ord t =&gt; Zip ((:-&gt;#) t) where
    FS xd xf `zip` FS yd yf = FS (xd `min` yd) (xf `zip` yf)
</code></pre>

<p><code>pure</code> produces a constant value going forever.
<code>(&lt;*&gt;)</code> applies functions to corresponding arguments, running out with the shorter.</p>

<pre><code>instance (Ord t, Bounded t) =&gt; Applicative ((:-&gt;#) t) where
    pure a = FS maxBound (const a)
    (&lt;*&gt;)  = zipWith ($)
</code></pre>

<h4><code>Copointed</code> and <code>Comonad</code></h4>

<p><code>extract</code> pulls out the initial value (like <code>head</code>).</p>

<pre><code>instance Num t =&gt; Copointed ((:-&gt;#) t) where
    extract (FS _ f) = f 0
</code></pre>

<p><code>duplicate</code> acts like <code>tails</code>.
The generated segments are progressivly <code>drop</code>ped versions of the original segment.</p>

<pre><code>instance Num t =&gt; Comonad ((:-&gt;#) t) where
    duplicate s = FS (length s) (flip drop s)
</code></pre>

<h4><code>Monad</code></h4>

<p>I don&#8217;t know if there is a monad instance for <code>((:-&gt;#) t)</code>.
Simple diagonalization doesn&#8217;t work for <code>join</code>, since the <em>n<sup>th</sup></em> segment might be shorter than <em>n</em>.</p>

<h3>What&#8217;s ahead?</h3>

<p>The instances above remind me strongly of type class instances for several common types.
Another post will tease out some patterns and reconstruct <code>(t :-&gt;# a)</code> out of standard components, so that most of the code above can disappear.</p>

<p>Another post incorporates <code>(t :-&gt;# a)</code> into a new model and implementation of relative-time, comonadic FRP.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=65&amp;md5=844ce48c997f35fb216e2d03108a8a21"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/sequences-streams-and-segments/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fsequences-streams-and-segments&amp;language=en_GB&amp;category=text&amp;title=Sequences%2C+streams%2C+and+segments&amp;description=What+kind+of+thing+is+a+movie%3F+Or+a+song%3F+Or+a+trajectory+from+point+A+to+point+B%3F+If+you%26%238217%3Bre+a+computer+programmer%2Fprogrammee%2C+you+might+say+that+such+things...&amp;tags=applicative+functor%2Ccomonad%2CFRP%2Cfunction%2Cfunctional+reactive+programming%2Cfunctor%2Cmonoid%2Csequence%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
