<?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; fold</title>
	<atom:link href="http://conal.net/blog/tag/fold/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>Deriving list scans</title>
		<link>http://conal.net/blog/posts/deriving-list-scans</link>
		<comments>http://conal.net/blog/posts/deriving-list-scans#comments</comments>
		<pubDate>Tue, 22 Feb 2011 20:42:40 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[program derivation]]></category>
		<category><![CDATA[scan]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=341</guid>
		<description><![CDATA[I&#8217;ve been playing with deriving efficient parallel, imperative implementations of &#34;prefix sum&#34; or more generally &#34;left scan&#34;. Following posts will explore the parallel &#38; imperative derivations, but as a warm-up, I&#8217;ll tackle the functional &#38; sequential case here. FoldsYou&#8217;re probably familiar with the higher-order functions for left and right &#34;fold&#34;. The current documentation says: foldl, [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- teaser -->

<p
>I&#8217;ve been playing with deriving efficient parallel, imperative implementations of &quot;prefix sum&quot; or more generally &quot;left scan&quot;. Following posts will explore the parallel &amp; imperative derivations, but as a warm-up, I&#8217;ll tackle the functional &amp; sequential case here.</p
>

<div id="folds"
><h3
  >Folds</h3
  ><p
  >You&#8217;re probably familiar with the higher-order functions for left and right &quot;fold&quot;. The current documentation says:</p
  ><blockquote>
<p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:foldl"
    ><code
      >foldl</code
      ></a
    >, applied to a binary operator, a starting value (typically the left-identity of the operator), and a list, reduces the list using the binary operator, from left to right:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldl</span
      > f z [x1, x2, &#8943;, xn] &#8801; (&#8943;((z <span class="ot"
      >`f`</span
      > x1) <span class="ot"
      >`f`</span
      > x2) <span class="ot"
      >`f`</span
      >&#8943;) <span class="ot"
      >`f`</span
      > xn<br
       /></code
    ></pre
  ><p
  >The list must be finite.</p
  ><p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:foldr"
    ><code
      >foldr</code
      ></a
    >, applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldr</span
      > f z [x1, x2, &#8943;, xn] &#8801; x1 <span class="ot"
      >`f`</span
      > (x2 <span class="ot"
      >`f`</span
      > &#8943; (xn <span class="ot"
      >`f`</span
      > z)&#8943;)<br
       /></code
    ></pre
  ></blockquote>
<p
  >And here are typical definitions:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; b<br
       /><span class="fu"
      >foldl</span
      > f z []     <span class="fu"
      >=</span
      > z<br
       /><span class="fu"
      >foldl</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > <span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs<br
       /><br
       /><span class="fu"
      >foldr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; b<br
       /><span class="fu"
      >foldr</span
      > f z []     <span class="fu"
      >=</span
      > z<br
       /><span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > x <span class="ot"
      >`f`</span
      > <span class="fu"
      >foldr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >Notice that <code
    >foldl</code
    > builds up its result one step at a time and reveals it all at once, in the end. The whole result value is locked up until the entire input list has been traversed. In contrast, <code
    >foldr</code
    > starts revealing information right away, and so works well with infinite lists. Like <code
    >foldl</code
    >, <code
    >foldr</code
    > also yields only a final value.</p
  ><p
  >Sometimes it's handy to also get to all of the intermediate steps. Doing so takes us beyond the land of folds to the kingdom of scans.</p
  ></div
>

<div id="scans"
><h3
  >Scans</h3
  ><p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanl"
    ><code
      >scanl</code
      ></a
    > and <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanr"
    ><code
      >scanr</code
      ></a
    > functions correspond to <code
    >foldl</code
    > and <code
    >foldr</code
    > but produce <em
    >all</em
    > intermediate accumulations, not just the final one.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><br
       /><span class="fu"
      >scanl</span
      > f z [x1, x2,  &#8943; ] &#8801; [z, z <span class="ot"
      >`f`</span
      > x1, (z <span class="ot"
      >`f`</span
      > x1) <span class="ot"
      >`f`</span
      > x2, &#8943;]<br
       /><br
       /><span class="fu"
      >scanr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><br
       /><span class="fu"
      >scanr</span
      > f z [&#8943;, xn_1, xn] &#8801; [&#8943;, xn_1 <span class="ot"
      >`f`</span
      > (xn <span class="ot"
      >`f`</span
      > z), xn <span class="ot"
      >`f`</span
      > z, z]<br
       /></code
    ></pre
  ><p
  >As you might expect, the last value is the complete left fold, and the <em
    >first</em
    > value in the scan is the complete <em
    >right</em
    > fold:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > (<span class="fu"
      >scanl</span
      > f z xs) &#8801; <span class="fu"
      >foldl</span
      > f z xs<br
       /><span class="fu"
      >head</span
      > (<span class="fu"
      >scanr</span
      > f z xs) &#8801; <span class="fu"
      >foldr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >which is to say</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > &#8728; <span class="fu"
      >scanl</span
      > f z &#8801; <span class="fu"
      >foldl</span
      > f z<br
       /><span class="fu"
      >head</span
      > &#8728; <span class="fu"
      >scanr</span
      > f z &#8801; <span class="fu"
      >foldr</span
      > f z<br
       /></code
    ></pre
  ><p
  >The standard scan definitions are trickier than the fold definitions:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><span class="fu"
      >scanl</span
      > f z ls <span class="fu"
      >=</span
      > z <span class="fu"
      >:</span
      > (<span class="kw"
      >case</span
      > ls <span class="kw"
      >of</span
      ><br
       />                     []   &#8594; []<br
       />                     x<span class="fu"
      >:</span
      >xs &#8594; <span class="fu"
      >scanl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs)<br
       /><br
       /><span class="fu"
      >scanr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><span class="fu"
      >scanr</span
      > _ z []     <span class="fu"
      >=</span
      > [z]<br
       /><span class="fu"
      >scanr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > (x <span class="ot"
      >`f`</span
      > q) <span class="fu"
      >:</span
      > qs<br
       />                   <span class="kw"
      >where</span
      > qs<span class="fu"
      >@</span
      >(q<span class="fu"
      >:</span
      >_) <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >Every time I encounter these definitions, I have to walk through it again to see what's going on. I finally sat down to figure out how these tricky definitions might <em
    >emerge</em
    > from simpler specifications. In other words, how to <em
    >derive</em
    > these definitions systematically from simpler but less efficient definitions.</p
  ><p
  >Most likely, these derivations have been done before, but I learned something from the effort, and I hope you do, too.</p
  ><span id="more-341"></span></div
>

<div id="specifying-scans"
><h3
  >Specifying scans</h3
  ><p
  >As I pointed out above, the last element of a left scan is the left fold over the whole list. In fact, <em
    >all</em
    > of the elements are left folds, but over <em
    >prefixes</em
    > of the list. Similarly, all of the elements of a right-scan are right folds, but over <em
    >suffixes</em
    > of the list. These observations give rise to very simple specifications for <code
    >scanl</code
    > and <code
    >scanr</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > f z xs <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits xs)<br
       /><span class="fu"
      >scanr</span
      > f z xs <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails xs)<br
       /></code
    ></pre
  ><p
  >Equivalently,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > f z <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) &#8728; inits<br
       /><span class="fu"
      >scanr</span
      > f z <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) &#8728; tails<br
       /></code
    ></pre
  ><p
  >Here I'm using the standard <code
    >inits</code
    > and <code
    >tails</code
    > functions from <code
    >Data.List</code
    >, documented as follows:</p
  ><blockquote>
<p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:inits"
    ><code
      >inits</code
      ></a
    > function returns all initial segments of the argument, shortest first. For example,</p
  ><pre class="sourceCode haskell"
  ><code
    >inits <span class="st"
      >&quot;abc&quot;</span
      > &#8801; [<span class="st"
      >&quot;&quot;</span
      >,<span class="st"
      >&quot;a&quot;</span
      >,<span class="st"
      >&quot;ab&quot;</span
      >,<span class="st"
      >&quot;abc&quot;</span
      >]<br
       /></code
    ></pre
  ><p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:tails"
    ><code
      >tails</code
      ></a
    > function returns all final segments of the argument, longest first. For example,</p
  ><pre class="sourceCode haskell"
  ><code
    >tails <span class="st"
      >&quot;abc&quot;</span
      > &#8801; [<span class="st"
      >&quot;abc&quot;</span
      >, <span class="st"
      >&quot;bc&quot;</span
      >, <span class="st"
      >&quot;c&quot;</span
      >,<span class="st"
      >&quot;&quot;</span
      >]<br
       /></code
    ></pre
  ></blockquote>
<p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#inits"
    >The</a
    > <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#tails"
    >definitions</a
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >inits <span class="dv"
      >&#8759;</span
      > [a] &#8594; [[a]]<br
       />inits []     <span class="fu"
      >=</span
      > [[]]<br
       />inits (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > [[]] <span class="fu"
      >++</span
      > <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs)<br
       /><br
       />tails <span class="dv"
      >&#8759;</span
      > [a] &#8594; [[a]]<br
       />tails []         <span class="fu"
      >=</span
      > [[]]<br
       />tails xs<span class="fu"
      >@</span
      >(_<span class="fu"
      >:</span
      >xs') <span class="fu"
      >=</span
      > xs <span class="fu"
      >:</span
      > tails xs'<br
       /></code
    ></pre
  ><p
  >This definition of <code
    >inits</code
    > is stricter than necessary, as it examines its argument before emitting anything but ends up emitting an initial empty list whether the argument is nil or a cons. Here's a lazier definition:</p
  ><pre class="sourceCode haskell"
  ><code
    >inits xs <span class="fu"
      >=</span
      > [] <span class="fu"
      >:</span
      > <span class="kw"
      >case</span
      > xs <span class="kw"
      >of</span
      ><br
       />                  []     &#8594; []<br
       />                  (x<span class="fu"
      >:</span
      >xs) &#8594; <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs)<br
       /></code
    ></pre
  ><p
  >This second version produces the initial <code
    >[]</code
    > before examining its argument, which helps to avoid deadlock in some recursive contexts.</p
  ><p
  >These specifications of <code
    >scanl</code
    > and <code
    >scanr</code
    > make it very easy to prove the properties given above that</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > &#8728; <span class="fu"
      >scanl</span
      > f z &#8801; <span class="fu"
      >foldl</span
      > f z<br
       /><span class="fu"
      >head</span
      > &#8728; <span class="fu"
      >scanr</span
      > f z &#8801; <span class="fu"
      >foldr</span
      > f z<br
       /></code
    ></pre
  ><p
  >(Hint: use the fact that <code
    >last &#8728; inits &#8801; id</code
    >, and <code
    >head &#8728; tails &#8801; id</code
    >.)</p
  ><p
  >Although these specifications of <code
    >scanl</code
    > (via <code
    >map</code
    >, <code
    >foldl</code
    >/<code
    >foldr</code
    >, and <code
    >inits</code
    >/<code
    >tails</code
    >) state succinctly and simply <em
    >what</em
    > <code
    >scanl</code
    > and <code
    >scanr</code
    > compute, they are terrible recipes for <em
    >how</em
    >, because they perform quadratic work instead of linear.</p
  ><p
  >But that's okay, because now we're going to see how to turn these inefficient &amp; clear specifications into efficient &amp; less clear implementations.</p
  ></div
>

<div id="deriving-efficient-scans"
><h3
  >Deriving efficient scans</h3
  ><p
  >To derive efficient scans, use the specifications and perform some simplifications.</p
  ><p
  >Divide <code
    >scanl</code
    > into empty lists and nonempty lists, starting with empty:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanl</span
      > f z []<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits [])<br
       />&#8801; <span class="co"
      >{- inits def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) [[]]<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  [<span class="fu"
      >foldl</span
      > f z []]<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  [z]<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanl</span
      > f z (x<span class="fu"
      >:</span
      >xs)<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits (x<span class="fu"
      >:</span
      >xs))<br
       />&#8801; <span class="co"
      >{- inits def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) ([] <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  <span class="fu"
      >foldl</span
      > f z [] <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (<span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (<span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- map g &#8728; map f &#8801; map (g &#8728; f) -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z &#8728; (x<span class="fu"
      >:</span
      >)) (inits xs)<br
       />&#8801; <span class="co"
      >{- (&#8728;) def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (&#955; ys &#8594; <span class="fu"
      >foldl</span
      > f z (x<span class="fu"
      >:</span
      >ys)) (inits xs)<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (&#955; ys &#8594; <span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x) ys)) (inits xs)<br
       />&#8801; <span class="co"
      >{- &#951; reduction -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x))) (inits xs)<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >scanl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs<br
       /></code
    ></pre
  ><p
  >Combine these conclusions and factor out the common <code
    >(z : )</code
    > to yield the standard &quot;optimized&quot; definition.</p
  ><p
  >Does <code
    >scanr</code
    > work out similarly? Let's find out, replacing <code
    >scanl</code
    > with <code
    >scanr</code
    >, <code
    >foldl</code
    > with <code
    >foldr</code
    >, and <code
    >inits</code
    > with <code
    >tails</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanr</span
      > f z []<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails [])<br
       />&#8801; <span class="co"
      >{- tails def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) ([[]])<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  [<span class="fu"
      >foldr</span
      > f z []]<br
       />&#8801; <span class="co"
      >{- foldr def -}</span
      ><br
       />  [z]<br
       /></code
    ></pre
  ><p
  >The derivation for nonempty lists deviates from <code
    >scanl</code
    >, due to differences between <code
    >inits</code
    > and <code
    >tails</code
    >, but it all works out nicely.</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanr</span
      > f z (x<span class="fu"
      >:</span
      >xs)<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails (x<span class="fu"
      >:</span
      >xs))<br
       />&#8801; <span class="co"
      >{- tails def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) ((x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > tails xs)<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  <span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails xs)<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- foldr def -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >foldr</span
      > f z xs) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- head/scanr property -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >head</span
      > (<span class="fu"
      >scanr</span
      > f z xs)) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- factor out shared expression -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >head</span
      > qs) <span class="fu"
      >:</span
      > qs <span class="kw"
      >where</span
      > qs <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- stylistic variation -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > q) <span class="fu"
      >:</span
      > qs <span class="kw"
      >where</span
      > qs<span class="fu"
      >@</span
      >(q<span class="fu"
      >:</span
      >_) <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       /></code
    ></pre
  ></div
>

<div id="coming-attractions"
><h3
  >Coming attractions</h3
  ><p
  >The scan implementations above are thoroughly sequential, in that they thread a single linear chain of data dependencies throughout the computation. Upcoming posts will look at more parallel-friendly variations.</p
  ></div
>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=341&amp;md5=1d0b111320d43a274e7ac15b91118e5d"><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/deriving-list-scans/feed</wfw:commentRss>
		<slash:comments>5</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%2Fderiving-list-scans&amp;language=en_GB&amp;category=text&amp;title=Deriving+list+scans&amp;description=I%26%238217%3Bve+been+playing+with+deriving+efficient+parallel%2C+imperative+implementations+of+%26quot%3Bprefix+sum%26quot%3B+or+more+generally+%26quot%3Bleft+scan%26quot%3B.+Following+posts+will+explore+the+parallel+%26amp%3B+imperative+derivations%2C+but+as+a+warm-up%2C...&amp;tags=fold%2Cprogram+derivation%2Cscan%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Enhancing a Zip</title>
		<link>http://conal.net/blog/posts/enhancing-a-zip</link>
		<comments>http://conal.net/blog/posts/enhancing-a-zip#comments</comments>
		<pubDate>Sun, 16 Nov 2008 01:09:03 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[proof]]></category>
		<category><![CDATA[type class morphism]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=61</guid>
		<description><![CDATA[This post is part four of the zip folding series inspired by Max Rabkin&#8217;s Beautiful folding post. I meant to write one little post, but one post turned into four. When I sense that something can be made simpler/clearer, I can&#8217;t leave it be. To review: Part One related Max&#8217;s data representation of left folds [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Enhancing a Zip

Tags: applicative functor, functor, fold, zip, type class morphism, proof

URL: http://conal.net/blog/posts/enhancing-a-zip/

-->

<!-- references -->

<!-- teaser -->

<p>This post is part four of the zip folding series inspired by Max Rabkin&#8217;s <em><a href="http://squing.blogspot.com/2008/11/beautiful-folding.html" title="blog post by Max Rabkin">Beautiful folding</a></em> post.
I meant to write one little post, but one post turned into four.
When I sense that something can be made simpler/clearer, I can&#8217;t leave it be.</p>

<p>To review:</p>

<ul>
<li><a href="http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms" title="blog post">Part One</a> related Max&#8217;s data representation of left folds to type class morphisms, a pattern that&#8217;s been steering me lately toward natural (inevitable) design of libraries.</li>
<li><a href="http://conal.net/blog/posts/more-beautiful-fold-zipping" title="blog post">Part Two</a> simplified that representation to help get to the essence of zipping, and in doing so lost the expressiveness necessary to define <code>Functor</code>and <code>Applicative</code> instaces.</li>
<li><a href="http://conal.net/blog/posts/proofs-for-left-fold-zipping/" title="blog post">Part Three</a> proved the suitability of the zipping definitions in <a href="http://conal.net/blog/posts/more-beautiful-fold-zipping" title="blog post">Part Two</a>.</li>
</ul>

<p>This post shows how to restore the <code>Functor</code> and <code>Applicative</code> (very useful composition tools) to folds but does so in a way that leaves the zipping functionality untouched.
This new layer is independent of folding and can be layered onto <em>any zippable type</em>.</p>

<p>You can <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ZipFold" title="the ZipFold package">get the code</a> described below.</p>

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

<ul>
<li>2009-02-15: Simplified <code>WithCont</code>, collapsing two type parameters into one.  Added functor comment about <code>cfoldlc'</code>.</li>
</ul>

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

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

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

<p>Max&#8217;s fold type packages up the first two arguments of <code>foldl'</code> and adds on an post-fold step, as needed for <code>fmap</code>:</p>

<pre><code>data Fold b c = forall a. F (a -&gt; b -&gt; a) a (a -&gt; c)  -- clever version
</code></pre>

<p>The simpler, less clever version just has the two <code>foldl'</code> arguments, and no <code>forall</code>:</p>

<pre><code>data Fold b a = F (a -&gt; b -&gt; a) a                     -- simple version
</code></pre>

<p>Removing Max&#8217;s post-fold step gets to the essence of fold zipping but loses some useful composability.
In particular, we can no longer define <code>Functor</code> and <code>Applicative</code> instances.</p>

<p>The difference between the clever version and the simple one is a continuation and a <code>forall</code>, which we can write down as follows:</p>

<pre><code>data WithCont z c = forall a. WC (z a) (a -&gt; c)
</code></pre>

<p>The clever version is equivalent to the following:</p>

<pre><code>type FoldC b = WithCont (Fold b)
</code></pre>

<p>Interpreting a <code>FoldC</code> just interprets the <code>Fold</code> and then applies the continuation:</p>

<pre><code>cfoldlc :: FoldC b a -&gt; [b] -&gt; a
cfoldlc (WC f k) = k . cfoldl f
</code></pre>

<p>(In a more general setting, use <code>fmap</code> in place of <code>(.)</code> to give meaning to <code>WithCont</code>.)</p>

<p>Add a copy of <code>WithCont</code>, for reasons explained later, and use it for strict folds.</p>

<pre><code>data WithCont' z c = forall a. WC' (z a) (a -&gt; c)

type FoldC' b = WithCont' (Fold b)

cfoldlc' :: FoldC' b a -&gt; [b] -&gt; a
cfoldlc' (WC' f k) = k . cfoldl' f
</code></pre>

<h3>From <code>Zip</code> to <code>Functor</code> and <code>Applicative</code></h3>

<p>It&#8217;s now a simple matter to recover the lost <code>Functor</code> and <code>Applicative</code> instances, for both non-strict and strict zipping.
The <code>Applicative</code> instances rely on zippability:</p>

<pre><code>instance Functor (WithCont z) where
  fmap g (WC f k) = WC f (g . k)

instance Zip z =&gt; Applicative (WithCont z) where
  pure a = WC undefined (const a)
  WC hf hk &lt;*&gt; WC xf xk =
    WC (hf `zip` xf) ( (a,a') -&gt; (hk a) (xk a'))


instance Functor (WithCont' z) where
  fmap g (WC' f k) = WC' f (g . k)

instance Zip' z =&gt; Applicative (WithCont' z) where
  pure a = WC' undefined (const a)
  WC' hf hk &lt;*&gt; WC' xf xk =
    WC' (hf `zip'` xf) ( (P a a') -&gt; (hk a) (xk a'))
</code></pre>

<p>Now the reason for the duplicate <code>WithCont</code> definition becomes apparent.
Instance selection in Haskell is based entirely on the &#8220;head&#8221; of an instance.
If both <code>Applicative</code> instances used <code>WithCont</code>, the compiler would consider them to overlap.</p>

<h3>Morphism proofs</h3>

<p>It remains to prove that our interpretation functions are <code>Functor</code> and <code>Applicative</code> morphisms.
I&#8217;ll show the non-strict proofs.
The strict morphism proofs go through similarly.</p>

<h4>Functor</h4>

<p>The <code>Functor</code> morphism property for non-strict folding:</p>

<pre><code>cfoldlc (fmap g wc) == fmap g (cfoldlc wc)
</code></pre>

<p>Adding some structure:</p>

<pre><code>cfoldlc (fmap g (WC f k)) == fmap g (cfoldlc (WC f k))
</code></pre>

<p>Proof:</p>

<pre><code>cfoldlc (fmap g (WC f k))

  == {- fmap on WithCont -}

cfoldlc (WC f (g . k))

  == {- cfoldlc def -}

(g . k) . cfoldl f

  == {- associativity of (.)  -}

g . (k . cfoldl f)

  == {- cfoldl def -}

g . cfoldlc (WC f k)

  == {- fmap on functions -}

fmap g (cfoldlc (WC f k))
</code></pre>

<h4>Applicative</h4>

<p><code>Applicative</code> has two methods, so <code>cfoldlc</code> must satisfy two morphism properties.
One for <code>pure</code>:</p>

<pre><code>cfoldlc (pure a) == pure a
</code></pre>

<p>Proof:</p>

<pre><code>cfoldlc (pure a)

  == {- pure on WithCont -}

cfoldlc (WC undefined (const a))

  == {- cfoldlc def -}

const a . cfoldl undefined

  == {- property of const -}

const a

  == {- pure on functions -}

pure a
</code></pre>

<p>And one for <code>(&lt;*&gt;)</code>:</p>

<pre><code>cfoldlc (wch &lt;*&gt; wcx) == cfoldlc wch &lt;*&gt; cfoldlc wcx
</code></pre>

<p>Adding structure:</p>

<pre><code>cfoldlc ((WC hf hk) &lt;*&gt; (WC xf xk)) == cfoldlc (WC hf hk) &lt;*&gt; cfoldlc (WC xf xk)
</code></pre>

<p>Proof:</p>

<pre><code>cfoldlc ((WC hf hk) &lt;*&gt; (WC xf xk))

  == {- (&lt;*&gt;) on WithCont -}

cfoldlc (WC (hf `zip` xf) ( (a,a') -&gt; (hk a) (xk a')))

  == {- cfoldlc def -}

( (a,a') -&gt; (hk a) (xk a')) . cfoldl (hf `zip` xf)

  == {- Zip morphism law for Fold -}

( (a,a') -&gt; (hk a) (xk a')) . (cfoldl hf `zip` cfoldl xf)

  == {- zip def on functions -}

( (a,a') -&gt; (hk a) (xk a')) .  bs -&gt; (cfoldl hf bs, cfoldl xf bs)

  == {- (.) def -}

 bs -&gt; (hk (cfoldl hf bs)) (xk (cfoldl xf bs))

  == {- (&lt;*&gt;) on functions -}

(hk . cfoldl hf bs) &lt;*&gt; (xk . cfoldl xf)

  == {- cfoldlc def, twice -}

cfoldlc (WC hf hk) &lt;*&gt; cfoldlc (WC xf xk)
</code></pre>

<p>That&#8217;s it.</p>

<p>I like that <code>WithCont</code> allows composing the morphism proofs, in addition to the implementations.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=61&amp;md5=5eb0b4e41def72139d912156d5ec8d84"><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/enhancing-a-zip/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%2Fenhancing-a-zip&amp;language=en_GB&amp;category=text&amp;title=Enhancing+a+Zip&amp;description=This+post+is+part+four+of+the+zip+folding+series+inspired+by+Max+Rabkin%26%238217%3Bs+Beautiful+folding+post.+I+meant+to+write+one+little+post%2C+but+one+post+turned+into+four....&amp;tags=applicative+functor%2Cfold%2Cfunctor%2Cproof%2Ctype+class+morphism%2Czip%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Proofs for left fold zipping</title>
		<link>http://conal.net/blog/posts/proofs-for-left-fold-zipping</link>
		<comments>http://conal.net/blog/posts/proofs-for-left-fold-zipping#comments</comments>
		<pubDate>Sat, 15 Nov 2008 21:30:31 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[proof]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=60</guid>
		<description><![CDATA[The post More beautiful fold zipping showed a formulation of left-fold zipping, simplified from the ideas in Max Rabkin&#8217;s Beautiful folding. I claimed that the semantic functions are the inevitable (natural) ones in that they preserve zipping stucture. This post gives the promised proofs. The correctness of fold zipping can be expressed as follows. Is [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Proofs for left fold zipping

Tags: fold, zip, proof

URL: http://conal.net/blog/posts/proofs-for-left-zip-folding/

-->

<!-- references -->

<!-- teaser -->

<p>The post <em><a href="http://conal.net/blog/posts/more-beautiful-fold-zipping" title="blog post">More beautiful fold zipping</a></em> showed a formulation of left-fold zipping, simplified from the ideas in Max Rabkin&#8217;s <em><a href="http://squing.blogspot.com/2008/11/beautiful-folding.html" title="blog post by Max Rabkin">Beautiful folding</a></em>.  I claimed that the semantic functions are the inevitable (natural) ones in that they preserve zipping stucture.
This post gives the promised proofs.</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-60"></span></p>

<p>The correctness of fold zipping can be expressed as follows.
Is <code>cfoldl</code> a <code>Zip</code> morphism, and is <code>cfoldl'</code> a <code>Zip'</code> morphism?
(See <em><a href="http://conal.net/blog/posts/more-beautiful-fold-zipping" title="blog post">More beautiful fold zipping</a></em> for definitions of these functions and classes, and see <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> for the notion of type class morphisms.)</p>

<h3>Non-strict</h3>

<p>The non-strict version is simpler, though less useful.
We want to prove</p>

<pre><code>cfoldl (f `zip` f') == cfoldl f `zip` cfoldl f'
</code></pre>

<p>First, substitute the definition of <code>zip</code> for functions.</p>

<pre><code>instance Zip ((-&gt;) u) where zip = liftA2 (,)
</code></pre>

<p>This definition is a standard one for zipping applicative functors.
Given the <code>Applicative</code> instance for functions, this <code>Zip</code> instance is equivalent to</p>

<pre><code>instance Zip ((-&gt;) u) where r `zip` s =  u -&gt; (r u, s u)
</code></pre>

<p>So the <code>Zip</code> morphism property becomes</p>

<pre><code>cfoldl (f `zip` f') bs == (cfoldl f bs, cfoldl f' bs)
</code></pre>

<p>We&#8217;ll want some structure to our folds as well:</p>

<pre><code>cfoldl (F op e `zip` F op' e') bs
  == (cfoldl (F op e) bs, cfoldl (F op' e') bs)
</code></pre>

<p>Simplify the LHS:</p>

<pre><code>cfoldl (F op e `zip` F op' e') bs

  == {- Fold zip def -}

cfoldl (F op'' (e,e')) bs
  where (a,a') `op''` b = (a `op` b, a' `op'` b)

  == {- cfoldl def -}

foldl op'' (e,e') bs
  where (a,a') `op''` b = (a `op` b, a' `op'` b)
</code></pre>

<p>Then simplify the RHS:</p>

<pre><code>(cfoldl (F op e) bs, cfoldl (F op' e') bs)

  == {- cfoldl def -}

(foldl op e bs, foldl op' e' bs)
</code></pre>

<p>So the morphism law becomes</p>

<pre><code>foldl op'' (e,e') bs == (foldl op e bs, foldl op' e' bs)
  where
    (a,a') `op''` b = (a `op` b, a' `op'` b)
</code></pre>

<p>We&#8217;ll prove this form inductively in the list <code>bs</code>, using the definition of <code>foldl</code>:</p>

<pre><code>foldl :: (a -&gt; b -&gt; a) -&gt; a -&gt; [b] -&gt; a
foldl op a []     = a
foldl op a (b:bs) = foldl op (a `op` b) bs
</code></pre>

<p>First, empty lists.</p>

<pre><code>foldl op'' (e,e') [] where op'' = ...

  == {- foldl def  -}

(e,e')

  == {- foldl def, twice -}

(foldl op e [], foldl op' e' [])
</code></pre>

<p>Next, non-empty lists.</p>

<pre><code>foldl op'' (e,e') (b:bs) where op'' = ...

  == {- foldl def -}

foldl op'' ((e,e') `op''` b) bs where op'' = ...

  == {- op'' definition -}

foldl op'' (e `op` b, e' `op'` b) bs where op'' = ...

  == {- induction hypothesis -}

(foldl op (e `op` b) bs, foldl op' (e' `op'` b) bs)

  == {- foldl def, twice -}

(foldl op e (b:bs), foldl op' e' (b:bs))
</code></pre>

<h3>Strict</h3>

<p>The morphism law:</p>

<pre><code>cfoldl' (f `zip'` f') == cfoldl' f `zip'` cfoldl' f'
</code></pre>

<p>which simplifies to</p>

<pre><code>foldl' op'' (P e e') bs == P (foldl' op e bs) (foldl' op' e' bs)
  where
    P a a' `op''` b = P (a `op` b) (a' `op'` b)
</code></pre>

<p>This property can be proved similarly to the non-strict version.
The new aspect is manipulating the use of <code>seq</code>.</p>

<p>Again, use induction on lists, guided by the fold definition:</p>

<pre><code>foldl' :: (a -&gt; b -&gt; a) -&gt; a -&gt; [b] -&gt; a
foldl' op a []     = a
foldl' op a (b:bs) =
  let a' = a `op` b in a' `seq` foldl' f a' bs
</code></pre>

<p>First, empty lists.</p>

<pre><code>foldl op'' (P e e') [] where op'' = ...

  == {- foldl def  -}

P e e'

  == {- foldl def, twice -}

P (foldl op e []) (foldl op' e' [])
</code></pre>

<p>Next, non-empty lists.
For simplicity, I&#8217;ll inline the <code>let</code> in the definition of <code>foldl'</code> (which affects performance but not meaning):</p>

<pre><code>foldl' op'' (P e e') (b:bs) where op'' = ...

  == {- foldl' def -}

((P e e') `op''` b) `seq`
foldl' op'' ((P e e') `op''` b) bs where op'' = ...

  == {- op'' definition -}

P (e `op` b) (e' `op'` b) `seq`
foldl' op'' (P (e `op` b) (e' `op'` b)) bs

  == {- induction hypothesis -}

P (e `op` b) (e' `op'` b) `seq`
P (foldl' op (e `op` b) bs) (foldl' op' (e' `op` b) bs)

  == {- P strictness -}

P (e `op` b) (e' `op'` b) `seq`
P ((e  `op` b) `seq` foldl' op  (e  `op` b) bs)
  ((e' `op` b) `seq` foldl' op' (e' `op` b) bs)

  == {- foldl' def, twice -}

P (foldl' op e (b:bs)) (foldl' op' e' (b:bs))
</code></pre>

<p>That&#8217;s it.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=60&amp;md5=715461026a2854a157ac9887e1eb8b59"><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/proofs-for-left-fold-zipping/feed</wfw:commentRss>
		<slash:comments>4</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%2Fproofs-for-left-fold-zipping&amp;language=en_GB&amp;category=text&amp;title=Proofs+for+left+fold+zipping&amp;description=The+post+More+beautiful+fold+zipping+showed+a+formulation+of+left-fold+zipping%2C+simplified+from+the+ideas+in+Max+Rabkin%26%238217%3Bs+Beautiful+folding.+I+claimed+that+the+semantic+functions+are+the+inevitable...&amp;tags=fold%2Cproof%2Czip%2Cblog" type="text/html" />
	</item>
		<item>
		<title>More beautiful fold zipping</title>
		<link>http://conal.net/blog/posts/more-beautiful-fold-zipping</link>
		<comments>http://conal.net/blog/posts/more-beautiful-fold-zipping#comments</comments>
		<pubDate>Sat, 15 Nov 2008 07:24:21 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=59</guid>
		<description><![CDATA[My previous post, Another lovely example of type class morphisms, placed some standard structure around Max Rabkin&#8217;s Beautiful folding, using type class morphisms to confirm that the Functor and Applicative instances agreed with their inevitable meanings. In the process of working out the Applicative case, I realized the essence of fold zipping was getting a [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: More beautiful fold zipping

Tags: fold, zip

URL: http://conal.net/blog/posts/more-beautiful-fold-zipping

-->

<!-- references -->

<!-- teaser -->

<p>My previous post, <em><a href="http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms" title="blog post">Another lovely example of type class morphisms</a></em>, placed some standard structure around Max Rabkin&#8217;s <em><a href="http://squing.blogspot.com/2008/11/beautiful-folding.html" title="blog post by Max Rabkin">Beautiful folding</a></em>, using <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">type class morphisms</a> to confirm that the <code>Functor</code> and <code>Applicative</code> instances agreed with their inevitable meanings.</p>

<p>In the process of working out the <code>Applicative</code> case, I realized the essence of fold zipping was getting a bit obscured.
This post simplifies Max&#8217;s <code>Fold</code> data type a bit and shows how to zip strict left folds in the simpler setting.
You can <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ZipFold" title="the ZipFold package">get the code</a> described here.</p>

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

<ul>
<li>2008-11-15: I renamed the <code>Pair</code> and <code>Pair'</code> classes to <code>Zip</code> and <code>Zip'</code>.</li>
</ul>

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

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

<h3>A simpler fold</h3>

<p>The strict left-folding functional is</p>

<pre><code>foldl' :: (a -&gt; b -&gt; a) -&gt; a -&gt; [b] -&gt; a
</code></pre>

<p>Max&#8217;s fold type packages up the first two arguments of <code>foldl'</code> and adds on an post-fold step, as needed for <code>fmap</code>:</p>

<pre><code>data Fold b c = forall a. F (a -&gt; b -&gt; a) a (a -&gt; c)  -- clever version
</code></pre>

<p>A simpler, less clever version just has the two <code>foldl'</code> arguments, and no <code>forall</code>:</p>

<pre><code>data Fold b a = F (a -&gt; b -&gt; a) a  -- simple version
</code></pre>

<p>I&#8217;ll use this simpler version for zipping and later enhance it for <code>fmap</code>.</p>

<p>The strict interpretation of <code>Fold</code> simply unpacks and folds:</p>

<pre><code>cfoldl' :: Fold b a -&gt; [b] -&gt; a
cfoldl' (F op e) = foldl' op e
</code></pre>

<p>Zipping is then just a simplification of the <code>(&lt;*&gt;)</code> definition in <a href="http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms" title="blog post">the previous post</a>.
As before, <code>P</code> is a type and constructor of strict pairs.</p>

<pre><code>data P c c' = P !c !c'

zipF' :: Fold b a -&gt; Fold b a' -&gt; Fold b (P a a')
F op e `zipF'` F op' e' = F op'' (P e e')
 where
   P a a' `op''` b = P (a `op` b) (a' `op'` b)
</code></pre>

<p>We can also define non-strict counterparts:</p>

<pre><code>cfoldl :: Fold b a -&gt; [b] -&gt; a
cfoldl (F op e) = foldl op e

zipF :: Fold b a -&gt; Fold b a' -&gt; Fold b (a,a')
F op e `zipF` F op' e' = F op'' (e,e')
 where
   (a,a') `op''` b = (a `op` b, a' `op'` b)
</code></pre>

<h3>More type classes &#8230;</h3>

<p>A <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">previous post</a> suggested a criterion for inevitability of interpretation functions like <code>cfoldl</code> and <code>cfoldl'</code>.
Whatever class instances exists for the source type (<code>Fold</code> here), interpretation functions should be
&#8220;type class morphisms&#8221; for those classes, which loosely means that the meaning of a method is the same method on the meaning.</p>

<p>Where&#8217;s the type class for our simplified <code>Fold</code>?
It lacks the magic ingredient Max added to make it a <code>Functor</code> and an <code>Applicative</code>, namely the post-fold step.</p>

<p>However, there&#8217;s <a href="http://hackage.haskell.org/packages/archive/TypeCompose/latest/doc/html/Data-Pair.html" title="module from the TypeCompose package">another class</a> that&#8217;s just the thing:</p>

<pre><code>class Zip f where zip :: f a -&gt; f b -&gt; f (a,b)
</code></pre>

<p>(I&#8217;ve used this class with type representations and user interfaces.)</p>

<p>The <code>Zip</code> class from <code>TypeCompose</code> is almost identical to <a href="http://hackage.haskell.org/packages/archive/category-extras/latest/doc/html/Control-Functor-Zip.html" title="module from the category-extras package">the <code>Zip</code> class</a> in <code>category-extras</code>.
The latter class requires <code>Functor</code>, however, which is too restrictive for the simplified <code>Fold</code> type.</p>

<p>Our <em>non-strict</em> left folds have a <code>Zip</code> instance:</p>

<pre><code>instance Zip (Fold b) where zip = zipF
</code></pre>

<p>For strict folds, define a strict variant on <code>Zip</code>:</p>

<pre><code>class Zip' f where zip' :: f a -&gt; f b -&gt; f (P a b)
</code></pre>

<p>and a <code>Zip'</code> instance for <code>Fold</code>:</p>

<pre><code>instance Zip' (Fold b) where zip' = zipF'
</code></pre>

<h3>&#8230; and more morphisms</h3>

<p>These zipping classes have associated morphism properties.
A function <code>q</code> mapping from one <code>Zip</code> instance to another is a &#8220;<code>Zip</code> morphism&#8221; when</p>

<pre><code>q (f `zip` g) == q f `zip` q g
</code></pre>

<p>for all folds <code>f</code> and <code>g</code>.</p>

<p>Similarly for <code>Zip'</code> morphisms:</p>

<pre><code>q (f `zip'` g) == q f `zip'` q g
</code></pre>

<p>In other words, <code>q</code> distributes over <code>zip</code> or <code>zip'</code>.</p>

<p>As I&#8217;ll show in another post, the two interpretation functions <code>cfoldl</code> and <code>cfoldl'</code> are <code>Zip</code> and <code>Zip'</code> morphisms, respectively, i.e.,</p>

<pre><code>cfoldl  (f `zip`  g) == cfoldl  f `zip`  cfoldl  g

cfoldl' (f `zip'` g) == cfoldl' f `zip'` cfoldl' g
</code></pre>

<p>which means that zip folding as defined above works correctly.</p>

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

<p>I like to keep blog posts fairly short, so I&#8217;ll share two more pieces of this story in upcoming blog posts:</p>

<ul>
<li>Regaining the lost <code>Functor</code> and <code>Applicative</code> instances.</li>
<li>The <code>Zip</code> and <code>Zip'</code> morphism proofs for zip folding.</li>
</ul>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=59&amp;md5=f493b4d0c5d54a87e384633fe21bd7aa"><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/more-beautiful-fold-zipping/feed</wfw:commentRss>
		<slash:comments>7</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%2Fmore-beautiful-fold-zipping&amp;language=en_GB&amp;category=text&amp;title=More+beautiful+fold+zipping&amp;description=My+previous+post%2C+Another+lovely+example+of+type+class+morphisms%2C+placed+some+standard+structure+around+Max+Rabkin%26%238217%3Bs+Beautiful+folding%2C+using+type+class+morphisms+to+confirm+that+the+Functor+and+Applicative...&amp;tags=fold%2Czip%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Another lovely example of type class morphisms</title>
		<link>http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms</link>
		<comments>http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms#comments</comments>
		<pubDate>Fri, 14 Nov 2008 06:20:06 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[semantics]]></category>
		<category><![CDATA[type class]]></category>
		<category><![CDATA[type class morphism]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=58</guid>
		<description><![CDATA[I read Max Rabkin&#8217;s recent post Beautiful folding with great excitement. He shows how to make combine multiple folds over the same list into a single pass, which can then drastically reduce memory requirements of a lazy functional program. Max&#8217;s trick is giving folds a data representation and a way to combine representations that corresponds [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Another lovely example of type class morphisms

Tags: applicative functor, functor, type class morphism, semantics, type class, fold, zip

URL: http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms/

-->

<!-- references -->

<!-- teaser -->

<p>I read Max Rabkin&#8217;s recent post <a href="http://squing.blogspot.com/2008/11/beautiful-folding.html" title="blog post by Max Rabkin">Beautiful folding</a> with great excitement.
He shows how to make combine multiple folds over the same list into a single pass, which can then drastically reduce memory requirements of a lazy functional program.
Max&#8217;s trick is giving folds a data representation and a way to combine representations that corresponds to combining the folds.</p>

<p>Peeking out from behind Max&#8217;s definitions is a lovely pattern I&#8217;ve been noticing more and more over the last couple of years, namely <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">type class morphisms</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-58"></span></p>

<h3>Folds as data</h3>

<p>Max gives a data representation of folds and adds on an post-fold step, which makes them composable.</p>

<pre><code>data Fold b c = forall a. F (a -&gt; b -&gt; a) a (a -&gt; c)
</code></pre>

<p>The components of a <code>Fold</code> are a (strict left) fold&#8217;s combiner function and initial value, plus a post-fold step.
This interpretation is done by a function <code>cfoldl'</code>, which turns these data folds into function folds:</p>

<pre><code>cfoldl' :: Fold b c -&gt; [b] -&gt; c
cfoldl' (F op e k) = k . foldl' op e
</code></pre>

<p>where <code>foldl'</code> is the standard strict, left-fold functional:</p>

<pre><code>foldl' :: (a -&gt; b -&gt; a) -&gt; a -&gt; [b] -&gt; a
foldl' op a []     = a
foldl' op a (b:bs) =
  let a' = a `op` b in a' `seq` foldl' f a' bs
</code></pre>

<h3>Standard classes</h3>

<p>As Twan van Laarhoven pointed out in a comment on <a href="http://squing.blogspot.com/2008/11/beautiful-folding.html" title="blog post by Max Rabkin">Max&#8217;s post</a>, <code>Fold b</code> is a functor and an applicative functor, so some of Max&#8217;s <code>Fold</code>-manipulating functions can be replaced by standard vocabulary.</p>

<p>The <code>Functor</code> instance is pretty simple:</p>

<pre><code>instance Functor (Fold b) where
  fmap h (F op e k) = F op e (h . k)
</code></pre>

<p>The <code>Applicative</code> instance is a bit trickier.
For strictness, Max used used a type of strict pairs:</p>

<pre><code>data Pair c c' = P !c !c'
</code></pre>

<p>The instance:</p>

<pre><code>instance Applicative (Fold b) where
  pure a = F (error "no op") (error "no e") (const a)

  F op e k &lt;*&gt; F op' e' k' = F op'' e'' k''
   where
     P a a' `op''` b = P (a `op` b) (a' `op'` b)
     e''             = P e e'
     k'' (P a a')    = (k a) (k' a')
</code></pre>

<p>Given that <code>Fold b</code> is an applicative functor, Max&#8217;s <code>bothWith</code> function is then <code>liftA2</code>.
Max&#8217;s <code>multi-cfoldl'</code> rule then becomes:</p>

<pre><code>forall c f g xs.
   h (cfoldl' f xs) (cfoldl' g xs) == cfoldl' (liftA2 h f g) xs
</code></pre>

<p>thus replacing two passes with one pass.</p>

<h3>Beautiful properties</h3>

<p>Now here&#8217;s the fun part.
Looking at the <code>Applicative</code> instance for <code>((-&gt;) a)</code>, the rule above is equivalent to</p>

<pre><code>forall c f g.
  liftA2 h (cfoldl' f) (cfoldl' g) == cfoldl' (liftA2 h f g)
</code></pre>

<p>Flipped around, this rule says that <code>liftA2</code> distributes over <code>cfoldl'</code>.
Or, &#8220;the meaning of <code>liftA2</code> is <code>liftA2</code>&#8220;.
Neat, huh?</p>

<p>Moreover, this <code>liftA2</code> property is equivalent to the following:</p>

<pre><code>forall f g.
  cfoldl' f &lt;*&gt; cfoldl' g == cfoldl' (f &lt;*&gt; g)
</code></pre>

<p>This form is one of the two <code>Applicative</code> morphism laws (which I usually write in the reverse direction):</p>

<p>For more about these morphisms, see <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Simplifying semantics with type class morphisms</a>.
That post suggests that semantic functions in particular ought to be type class morphisms (and if not, then you&#8217;d have an abstraction leak).
And <code>cfoldl'</code> is a semantic function, in that it gives meaning to a <code>Fold</code>.</p>

<p>The other type class morphisms in this case are</p>

<pre><code>cfoldl' (pure a  ) == pure a

cfoldl' (fmap h f) == fmap h (cfoldl' f)
</code></pre>

<p>Given the <code>Functor</code> and <code>Applicative</code> instances of <code>((-&gt;) a)</code>, these two properties are equivalent to</p>

<pre><code>cfoldl' (pure a  ) == const a

cfoldl' (fmap h f) == h . cfoldl' f
</code></pre>

<p>or</p>

<pre><code>cfoldl' (pure a  ) xs == a

cfoldl' (fmap h f) xs == h (cfoldl' f xs)
</code></pre>

<h3>Rewrite rules</h3>

<p>Max pointed out that GHC does not handle his original <code>multi-cfoldl'</code> rule.
The reason is that the head of the LHS (left-hand side) is a variable.
However, the type class morphism laws have constant (known) functions at the head, so I expect they could usefully act as fusion rewrite rules.</p>

<h3>Inevitable instances</h3>

<p>Given the implementations (instances) of <code>Functor</code> and <code>Applicative</code> for <code>Fold</code>, I&#8217;d like to verify that the morphism laws for <code>cfoldl'</code> (above) hold.</p>

<h4>Functor</h4>

<p>Start with <code>fmap</code>.
The morphism law:</p>

<pre><code>cfoldl' (fmap h f) == fmap h (cfoldl' f)
</code></pre>

<p>First, give the <code>Fold</code> argument more structure, so that (without loss of generality) the law becomes</p>

<pre><code>cfoldl' (fmap h (F op e k)) == fmap h (cfoldl' (F op e k))
</code></pre>

<p>The game is to work backward from this law to the definition of <code>fmap</code> for <code>Fold</code>.
I&#8217;ll do so by massaging the RHS (right-hand side) into the form <code>cfoldl' (...)</code>, where &#8220;<code>...</code>&#8221; is the definition <code>fmap h (F op e k)</code>.</p>

<pre><code>fmap h (cfoldl' (F op e k))

  ==  {- inline cfoldl' -}

fmap h (k . foldl' op e)

  ==  {- inline fmap on functions -}

h . (k . foldl' op e)

  ==  {- associativity of (.) -}

(h . k) . foldl' op e

  ==  {- uninline cfoldl' -}

cfoldl' (F op e (h . k))

  ==  {- uninline fmap on Fold  -}

cfoldl' (fmap h (F op e k))
</code></pre>

<p>This proof show why Max had to add the post-fold function <code>k</code> to his <code>Fold</code> type.
If <code>k</code> weren&#8217;t there, we couldn&#8217;t have buried the <code>h</code> in it.</p>

<p>More usefully, this proof suggests how we could have discovered the <code>fmap</code> definition.
For instance, we might have tried with a simpler and more obvious <code>Fold</code> representation:</p>

<pre><code>data FoldS a b = FS (a -&gt; b -&gt; a) a
</code></pre>

<p>Getting into the <code>fmap</code> derivation, we&#8217;d come to</p>

<pre><code>h . foldsl' op e
</code></pre>

<p>and then we&#8217;d be stuck.
But not really, because the awkward extra bit (<code>h .</code>) beckons us to generalize by adding Max&#8217;s post-fold function.</p>

<h4>Applicative</h4>

<p>Next pure:</p>

<pre><code>cfoldl' (pure a) == pure a
</code></pre>

<p>Reason as before, starting with the RHS</p>

<pre><code>pure a

  ==  {- inline pure on functions -}

const a

  ==  {- property of const -}

const a . foldl op e

  ==  {- uninline cfoldl' -}

cfoldl' (F (const a) op e)
</code></pre>

<p>The imaginative step was inventing structure to match the definition of <code>cfoldl'</code>.
This definition is true for <em>any</em> values of <code>op</code> and <code>e</code>, so we can use bottom in the definition:</p>

<pre><code>instance Applicative (Fold b) where
  pure a = F undefined undefined (const a)
</code></pre>

<p>As Twan noticed, the existential (<code>forall</code>) also lets us pick defined values for <code>op</code> and <code>e</code>.
He chose <code>(_ _ -&gt; ())</code> and <code>()</code>.</p>

<p>The derivation of <code>(&lt;*&gt;)</code> is trickier and is the heart of the problem of fusing folds to reduce multiple traversals to a single one.
Why the heart?  Because <code>(&lt;*&gt;)</code> is all about <em>combining</em> two things into one.</p>

<h4>Intermission</h4>

<p>I&#8217;m taking a break here.
While fiddling with a proof of the <code>(&lt;*&gt;)</code> morphism law, I realized a simpler way to structure these folds, which will be the topic of an upcoming post.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=58&amp;md5=654d33555237a7a03d4b82df83d84d6f"><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/another-lovely-example-of-type-class-morphisms/feed</wfw:commentRss>
		<slash:comments>2</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%2Fanother-lovely-example-of-type-class-morphisms&amp;language=en_GB&amp;category=text&amp;title=Another+lovely+example+of+type+class+morphisms&amp;description=I+read+Max+Rabkin%26%238217%3Bs+recent+post+Beautiful+folding+with+great+excitement.+He+shows+how+to+make+combine+multiple+folds+over+the+same+list+into+a+single+pass%2C+which+can+then...&amp;tags=applicative+functor%2Cfold%2Cfunctor%2Csemantics%2Ctype+class%2Ctype+class+morphism%2Czip%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
