<?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>LAMBDAPHONE &#187; sorting</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/sorting/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:58:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>An alternative definition for Data.List.groupBy</title>
		<link>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/</link>
		<comments>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 18:15:50 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=318</guid>
		<description><![CDATA[<p>The function <a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:groupBy"><code>groupBy</code></a> from haskell&#8217;s standard library is defined in terms of <code>span</code>, the effect being that the supplied predicate function is used to compare the first element of a group with successive elements.</p>
<p>This isn&#8217;t clear from the&#8230; <a href="http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>The function <a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:groupBy"><code>groupBy</code></a> from haskell&#8217;s standard library is defined in terms of <code>span</code>, the effect being that the supplied predicate function is used to compare the first element of a group with successive elements.</p>
<p>This isn&#8217;t clear from the docs, and you might try to do this and wonder at the output you got:</p>
<blockquote><pre>*Main> groupBy (< =) [3,4,5,3,2,1,4,4,1,1,2,3,4,5,4,5,6,7]
[[3,4,5,3],[2],[1,4,4,1,1,2,3,4,5,4,5,6,7]]</pre>
</pre>
</blockquote>
<p><span id="more-318"></span></p>
<p>We can redefine <code>groupBy</code> as follows, so that the supplied predicate function compares adjacent elements one-by-one and returns <code>True</code> if they should be grouped together:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;groupBy' <span class="Statement">::</span>&nbsp;(a&nbsp;<span class="Statement">-&gt;</span>&nbsp;a&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span>)&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[[a]]<br />
<span class="Comment">&gt;</span>&nbsp;groupBy' c&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[]<br />
<span class="Comment">&gt;</span>&nbsp;groupBy' c&nbsp;(a<span class="Statement">:</span>as)&nbsp;<span class="Statement">=</span>&nbsp;(a<span class="Statement">:</span>ys)&nbsp;<span class="Statement">:</span>&nbsp;groupBy' c&nbsp;zs<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;(ys,zs)&nbsp;<span class="Statement">=</span>&nbsp;spanC&nbsp;a&nbsp;as<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanC&nbsp;_&nbsp;&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;([],&nbsp;[])<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanC&nbsp;a' (x<span class="Statement">:</span>xs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;a' <span class="Statement">`c`</span>&nbsp;x&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;(ps,qs)&nbsp;<span class="Statement">=</span>&nbsp;spanC&nbsp;x&nbsp;xs&nbsp;<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;(x<span class="Statement">:</span>ps,qs)<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;([],&nbsp;x<span class="Statement">:</span>xs)<br />
<br /></blockquote></p>
<p>Now we can use the <code>groupBy</code> function to return a list of ascending lists, like we (probably) wanted:</p>
<blockquote><pre>*Main> groupBy' (< =) [3,4,5,3,2,1,4,4,1,1,2,3,4,5,4,5,6,7]
[[3,4,5],[3],[2],[1,4,4],[1,1,2,3,4,5],[4,5,6,7]]</pre>
</pre>
</blockquote>
<p>The functionality is of course the same for <code>groupBy (==)</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Find a permutation given its Inversion Table</title>
		<link>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/</link>
		<comments>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 19:04:22 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=284</guid>
		<description><![CDATA[<p>Here is some code I whipped up in response to an <a href="http://www.reddit.com/r/coding/comments/a3ckw/programming_problem_find_a_permutation_given_its/">interesting problem posted on reddit.com/r/coding/</a>. It was a really interesting algorithm to work out:</p>
<p><blockquote class="vimblock"><br />
<br />
<span class="PreProc">import</span>&#160;Data.List (sortBy)<br />
<br />
<span class="Comment">-- takes an inversion list and converts</span></blockquote>&#8230; <a href="http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Here is some code I whipped up in response to an <a href="http://www.reddit.com/r/coding/comments/a3ckw/programming_problem_find_a_permutation_given_its/">interesting problem posted on reddit.com/r/coding/</a>. It was a really interesting algorithm to work out:</p>
<p><blockquote class="vimblock"><br>
<br>
<span class="PreProc">import</span>&nbsp;Data.List (sortBy)<br>
<br>
<span class="Comment">-- takes an inversion list and converts it to the list of permuted</span><br>
<span class="Comment">-- elements:</span><br>
decode&nbsp;<span class="Statement">=</span>&nbsp;dec&nbsp;[]&nbsp;<span class="Statement">.</span>&nbsp;sortBy&nbsp;lowHi&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">zip</span>&nbsp;[<span class="Constant">1</span><span class="Statement">..</span>]&nbsp;&nbsp;<span class="Type">where</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;dec&nbsp;as&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;as<br>
&nbsp;&nbsp;&nbsp;&nbsp;dec&nbsp;as&nbsp;((a,_)<span class="Statement">:</span>is)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;is' <span class="Statement">=</span>&nbsp;sortBy&nbsp;lowHi&nbsp;(decrementGT&nbsp;a&nbsp;is)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">in</span>&nbsp;dec&nbsp;(a<span class="Statement">:</span>as)&nbsp;is'<br>
<br>
<span class="Comment">-- decrement every inversion number by 1, for every tuple in which</span><br>
<span class="Comment">-- the element is greater than `a`:</span><br>
decrementGT&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Statement">\</span>(a',i)&nbsp;<span class="Statement">-&gt;</span>&nbsp;(a',&nbsp;<span class="Statement">if</span>&nbsp;a'<span class="Statement">&gt;</span>a&nbsp;<span class="Statement">then</span>&nbsp;i<span class="Statement">-</span><span class="Constant">1</span>&nbsp;<span class="Statement">else</span>&nbsp;i)&nbsp;)<br>
<br>
<span class="Comment">-- we sort by the inversion number, low to high. For elements with</span><br>
<span class="Comment">-- the same inversion number, we say that the greater element tuple</span><br>
<span class="Comment">-- should go before a lesser element:</span><br>
lowHi&nbsp;(a,i)&nbsp;(a',i')&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;i&nbsp;<span class="Statement">==</span>&nbsp;i'&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;<span class="Statement">if</span>&nbsp;a<span class="Statement">&gt;</span>a' <span class="Statement">then</span>&nbsp;<span class="Constant">LT</span>&nbsp;<span class="Statement">else</span>&nbsp;<span class="Constant">GT</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">compare</span>&nbsp;i&nbsp;i'<br>
<br></blockquote></p>
<p>It&#8217;s not the prettiest code I&#8217;ve written, but it&#8217;s pretty straight-forward and concise. Thanks for looking!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/11/find-a-permutation-given-its-inversion-table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Polishing a Functional Pearl: The Burrows-Wheeler Transform</title>
		<link>http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/</link>
		<comments>http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 22:22:52 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=262</guid>
		<description><![CDATA[<p><em>Here is a quick post to get me back into the swing of blogging:</em></p>
<p>I was looking through an old post on StackOverflow about <a href="http://www.haskell.org/haskellwiki/Research_papers/Functional_pearls">clever functional code</a>, and the best answer, given by <a href="http://stackoverflow.com/questions/1524750/what-is-your-favourite-cleverly-written-functional-code/1527026#1527026">&#8220;yairchu&#8221;</a> was a nice version&#8230; <a href="http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>Here is a quick post to get me back into the swing of blogging:</em></p>
<p>I was looking through an old post on StackOverflow about <a href="http://www.haskell.org/haskellwiki/Research_papers/Functional_pearls">clever functional code</a>, and the best answer, given by <a href="http://stackoverflow.com/questions/1524750/what-is-your-favourite-cleverly-written-functional-code/1527026#1527026">&#8220;yairchu&#8221;</a> was a nice version of the <a href="http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler%5Ftransform">Burrows-Wheeler Transform</a>, which is an algorithm for permuting a string such that it can be compressed more effectively by other algorithms. The code posted was (import Data.List assumed):</p>
<p><blockquote class="vimblock"><br>
bwp&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Ord</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
bwp&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">$</span>&nbsp;sort&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">zip</span>&nbsp;(rots&nbsp;xs)&nbsp;(rrot&nbsp;xs)<br>
rots&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">take</span>&nbsp;(<span class="Identifier">length</span>&nbsp;xs)&nbsp;(<span class="Identifier">iterate</span>&nbsp;lrot&nbsp;xs)<br>
lrot&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">tail</span>&nbsp;xs&nbsp;<span class="Statement">++</span>&nbsp;[<span class="Identifier">head</span>&nbsp;xs]<br>
rrot&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">last</span>&nbsp;xs&nbsp;<span class="Statement">:</span>&nbsp;<span class="Identifier">init</span>&nbsp;xs<br>
<br></blockquote></p>
<p>I saw I could improve/shorten this in a couple of obvious ways and came up with this:</p>
<p><blockquote class="vimblock"><br>
bwp&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Ord</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
bwp&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;sort&nbsp;<span class="Statement">.</span>&nbsp;rots&nbsp;<br>
rots&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">zip</span>&nbsp;(<span class="Identifier">tail</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">iterate</span>&nbsp;lrot&nbsp;xs)&nbsp;xs<br>
lrot&nbsp;(x<span class="Statement">:</span>xs)&nbsp;<span class="Statement">=</span>&nbsp;xs&nbsp;<span class="Statement">++</span>&nbsp;[x]<br>
<br></blockquote></p>
<p>Still unsatisfied and even more obsessed I came up with this final, prettiest version, before forcing myself to give it up already:</p>
<p><blockquote class="vimblock"><br>
bwp&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Ord</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
bwp&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;sort&nbsp;<span class="Statement">.</span>&nbsp;rots&nbsp;<br>
rots&nbsp;xs&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Identifier">zip</span>&nbsp;(lrot&nbsp;xs)&nbsp;xs<br>
lrot&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">tail</span>&nbsp;<span class="Statement">.</span>&nbsp;tails&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">cycle</span><br>
<br></blockquote></p>
<p>Unfortunately, this last version will croak if your string happens to look like &#8220;111111&#8243; or &#8220;cAbcAb&#8221; because sort will keep trying to compare infinites lists.</p>
<p><em><strong>Update: </strong> I did a short post on the <a href="http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/">Move To Front transform</a> as a follow-up to this post.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>List Grouping module released</title>
		<link>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/</link>
		<comments>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 01:09:55 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[sorting]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=202</guid>
		<description><![CDATA[<p><strong>EDIT:</strong> <em>Don&#8217;t use this package, but use instead <a href="http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html">Data.List.Split</a> by Brent Yorgey. I didn&#8217;t see that a package like his existed! This module will hopefully be removed from hackage if they can do that.</em></p>
<p>I just finished the initial&#8230; <a href="http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>EDIT:</strong> <em>Don&#8217;t use this package, but use instead <a href="http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html">Data.List.Split</a> by Brent Yorgey. I didn&#8217;t see that a package like his existed! This module will hopefully be removed from hackage if they can do that.</em></p>
<p>I just finished the initial release of a simple module called <a href="http://hackage.haskell.org/package/list-grouping">list-grouping</a> that contains functions to partition a list into sub-lists in various ways, based on some predicate or integer offset. Functions like these are a little awkward to write and I was surprised when I didn&#8217;t see anything on hackage! </p>
<p>Check out the package description and install it with:</p>
<blockquote><p>$ cabal install list-grouping</p></blockquote>
<p>Here is an example from a previous post to <a href="http://coder.bsimmons.name/blog/2009/03/building-a-tree-from-an-ordered-list/">build a binary tree from an in-order list</a>, which uses the above library:</p>
<p><blockquote class="vimblock"><br>
<span class="Type">module</span>&nbsp;Main<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span><br>
<br>
<span class="PreProc">import</span>&nbsp;Data.List.Grouping<br>
<br>
<span class="Type">data</span>&nbsp;Tree&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;Node&nbsp;a&nbsp;(Tree&nbsp;a)&nbsp;(Tree&nbsp;a)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;End<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br>
<br>
fromSorted&nbsp;<span class="Statement">::</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree&nbsp;a<br>
fromSorted&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldl</span>&nbsp;mkTree&nbsp;End&nbsp;<span class="Statement">.</span>&nbsp;splitWith&nbsp;[<span class="Constant">2</span><span class="Statement">^</span>n&nbsp;<span class="Statement">|</span>&nbsp;n<span class="Statement">&lt;-</span>[<span class="Constant">0</span><span class="Statement">..</span>]]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;mkTree&nbsp;l&nbsp;(n<span class="Statement">:</span>ns)&nbsp;<span class="Statement">=</span>&nbsp;Node&nbsp;n&nbsp;l&nbsp;(fromSorted&nbsp;ns)<br>
<br></blockquote></p>
<p>I&#8217;m sure the functions can be made more efficient, to take advantage of <a href="http://www.reddit.com/r/haskell/comments/96s3q/understanding_when_ghc_will_fuse_away/?sort=new">fusion or what-not</a>, and I hope the library will eventually contain the most efficient implementations possible.</p>
<p>I also am looking for suggestions for other useful list grouping functions to include. Send your suggestions along! You can get the darcs source with:</p>
<blockquote><p>$ darcs get http://coder.bsimmons.name/code/ListGrouping/ </p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/08/list-grouping-module-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Run-length Encoding</title>
		<link>http://coder.bsimmons.name/blog/2009/05/run-length-encoding/</link>
		<comments>http://coder.bsimmons.name/blog/2009/05/run-length-encoding/#comments</comments>
		<pubDate>Tue, 26 May 2009 23:27:03 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[short]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=168</guid>
		<description><![CDATA[<p>Just a quick implementation of a<a href="http://en.wikipedia.org/wiki/Run-length_encoding"> RLE algorithm</a> for lists in haskell. We compress a list by converting &#8220;runs&#8221; of consecutive elements into a tuple of the form: (run_length, element).</p>
<p><blockquote class="vimblock"><br />
<span class="PreProc">import</span>&#160;Data.List (group)<br />
<span class="PreProc">import</span>&#160;Control.Arrow<br />
<br />
<br />
runLengthEnc&#160;<span</blockquote>&#8230; <a href="http://coder.bsimmons.name/blog/2009/05/run-length-encoding/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Just a quick implementation of a<a href="http://en.wikipedia.org/wiki/Run-length_encoding"> RLE algorithm</a> for lists in haskell. We compress a list by converting &#8220;runs&#8221; of consecutive elements into a tuple of the form: (run_length, element).</p>
<p><blockquote class="vimblock"><br>
<span class="PreProc">import</span>&nbsp;Data.List (group)<br>
<span class="PreProc">import</span>&nbsp;Control.Arrow<br>
<br>
<br>
runLengthEnc&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Eq</span>&nbsp;a&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[(<span class="Type">Int</span>,a)]<br>
runLengthEnc&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Identifier">length</span>&nbsp;<span class="Statement">&amp;&amp;&amp;</span>&nbsp;<span class="Identifier">head</span>)&nbsp;<span class="Statement">.</span>&nbsp;group<br>
<br>
decode&nbsp;<span class="Statement">::</span>&nbsp;[(<span class="Type">Int</span>,&nbsp;a)]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
decode&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">concatMap</span>&nbsp;(<span class="Identifier">uncurry</span>&nbsp;<span class="Identifier">replicate</span>)<br>
<br></blockquote></p>
<p>If the <code>&#038;&#038;&</code> combinator looks foreign to you, check out David R. Maciver&#8217;s <a href="http://www.drmaciver.com/2007/08/playing-with-arrows/">very enlightening blog about Arrow functions</a>. </p>
<p>I&#8217;m always curious to see how naive-looking functions like the above compare in performance to a from-scratch implementation with explicit recursion, so I came up with the following:</p>
<p><blockquote class="vimblock"><br>
runLengthEnc' <span class="Statement">::</span>&nbsp;<span class="Type">Eq</span>&nbsp;a&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[(<span class="Type">Int</span>,a)]<br>
runLengthEnc' []&nbsp;<span class="Statement">=</span>&nbsp;[]<br>
runLengthEnc' (a<span class="Statement">:</span>as)&nbsp;<span class="Statement">=</span>&nbsp;run&nbsp;<span class="Constant">1</span>&nbsp;a&nbsp;as<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;run&nbsp;n&nbsp;x&nbsp;[]&nbsp;<span class="Statement">=</span>&nbsp;[(n,x)]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run&nbsp;n&nbsp;x&nbsp;(x2<span class="Statement">:</span>xss)&nbsp;<span class="Statement">|</span>&nbsp;x&nbsp;<span class="Statement">==</span>&nbsp;x2&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;run&nbsp;(n<span class="Statement">+</span><span class="Constant">1</span>)&nbsp;x&nbsp;xss<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;(n,x)&nbsp;<span class="Statement">:</span>&nbsp;run&nbsp;<span class="Constant">1</span>&nbsp;x2&nbsp;xss<br>
<br></blockquote></p>
<p>I tested both functions on a list of 100,000 random 1s and 0s and found the explicit version to be only marginally better performing, completing the list in <code>49 ticks &#038; 130Mb</code>, compared to <code>54 ticks &#038; 139 Mb</code> for the one-liner!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/05/run-length-encoding/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
