<?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; data</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/data/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>Lazy Arithmetic in Haskell</title>
		<link>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/</link>
		<comments>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 17:24:08 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[NumericTypes]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=372</guid>
		<description><![CDATA[<p><em>We don&#8217;t usually give much thought to Numeric data types beyond whether we want to work with integers or decimal numbers. And that is a shame! In this post I&#8217;ll look at how we can actually do arithmetic operations lazily,</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>We don&#8217;t usually give much thought to Numeric data types beyond whether we want to work with integers or decimal numbers. And that is a shame! In this post I&#8217;ll look at how we can actually do arithmetic operations lazily, and in the process hopefully reveal a bit about haskell&#8217;s numeric classes.</em></p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;LazyArithmetic<br />
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span><br />
<br /></div></p>
<p>We will be using <a href="http://hackage.haskell.org/package/numbers-2009.8.9">Lennart Augustsson&#8217;s <code>numbers</code> library</a> which can be installed from hackage with <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal-install</a>:</p>
<blockquote><p>$> cabal install numbers</p></blockquote>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.Number.Natural<br />
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.List(genericLength)<br />
<br /></div></p>
<p>Consider two functions: the Prelude function <code>sum</code> and <code>genericLength</code> from the List library:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Identifier">genericLength</span>&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Num</span>&nbsp;i)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[b]&nbsp;<span class="Statement">-&gt;</span>&nbsp;i<br />
<span class="Comment"></span>&nbsp;<span class="Identifier">sum</span>&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Num</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;a<br />
<br /></blockquote></p>
<p>&#8230;two simple functions that have the potential to be very expensive, depending on the length of the list and the values of the elements.<br />
<span id="more-372"></span><br />
Say for instance that all we want is to use:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;sumLengths&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">sum</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">map</span>&nbsp;genericLength<br />
<span class="Comment">&gt;</span><br />
<span class="Comment">&gt;</span>&nbsp;checkLengths&nbsp;as&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;(sumLengths&nbsp;as&nbsp;<span class="Statement">`div`</span>&nbsp;n)&nbsp;<span class="Statement">&gt;</span>&nbsp;<span class="Constant">2</span><br />
<br /></div></p>
<p>The <code>checkLengths</code> function above has to count every element of every element of every sub-list in order to return a <code>Bool</code> value, and if any of those lists are infinite our program will never terminate:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;hopeless&nbsp;<span class="Statement">=</span>&nbsp;checkLengths&nbsp;[[<span class="Constant">'a'</span><span class="Statement">..</span><span class="Constant">'z'</span>],&nbsp;[<span class="Constant">'0'</span>],&nbsp;<span class="Identifier">repeat</span>&nbsp;<span class="Constant">'Z'</span>]&nbsp;&nbsp;<span class="Constant">99</span><br />
<br /></div></p>
<p><em>&#8230;or so we might think!</em></p>
<h3>Lazy Natural Numbers</h3>
<p>It turns out we can solve our seemingly hopeless situation with a type signature:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;sumLengths&nbsp;<span class="Statement">::</span>&nbsp;[[b]]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Natural<br />
<br /></div></p>
<p>And suddenly, as if by magic:</p>
<blockquote><p><code>*LazyArithmetic> hopeless<br />
True</code></p></blockquote>
<p>What&#8217;s going on here? Well it turns out the problem is that Haskell&#8217;s built-in numeric types are boring, old-fashioned and (in some cases) just plain wrong. But let&#8217;s step behind the curtain and look at how the Data.Numbers library defines the Natural type internally:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Type">data</span>&nbsp;Natural&nbsp;<span class="Statement">=</span>&nbsp;Z&nbsp;<span class="Statement">|</span>&nbsp;S&nbsp;Natural<br />
<br /></blockquote></p>
<p>We see that we&#8217;re using an abstract data type to represent non-negative integers, and it looks nearly identical to our list type <code>[]</code>. The upshot of that is we gain, in our numeric type and arithmetic operations, the same type of laziness that lists afford us!</p>
<p>So in the above example, <code>hopeless</code>, we need only carry out the operations far enough to see that the result is <code>> 2</code>.</p>
<p>The numeric type in <code>Data.List.Natural</code> are actually known as <a href="http://www.haskell.org/haskellwiki/Peano_numbers">Peano numbers</a>. They are essentially just lists of units and, as you might imagine, are not the most efficient way to represent an integer.</p>
<p>But they are exactly what we want for this application. If we failed to realize that we could solve our problem with an appropriate numeric representation, we might try to rig up something like this:</p>
<p><div class="vimblock"><br />
<span class="Comment">&gt;</span>&nbsp;checkLengthsUnclear&nbsp;as&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">not</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">null</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">drop</span>&nbsp;(n<span class="Statement">*</span><span class="Constant">2</span>)&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">concat</span>&nbsp;as<br />
<br /></div></p>
<p>&#8230;which works identically to <code>checkLengths</code> with Peano Numbers, but completely obfuscates the intention of the function. As usual laziness gives us <em>expressive power</em> rather than an efficiency boost.</p>
<h3>Limitations, Haskell&#8217;s Numeric Type Classes, and the Numeric Prelude</h3>
<p>The <code>Data.Number.Natural</code> library is convenient because it provides Num and Integral instances so we can use the the Natural type with any function that is polymorphic on those classes.</p>
<p>The problem is <a href="http://hackage.haskell.org/packages/archive/numbers/2009.8.9/doc/html/src/Data-Number-Natural.html#line-44">the Num instance</a> is incomplete and error-prone: and that&#8217;s because a <a href="http://en.wikipedia.org/wiki/Natural_number">natural numbe</a>r type <em>shouldn&#8217;t be an instance of Num</em>! We can&#8217;t negate a Natural, which in turn makes subtraction dangerous, etc.</p>
<blockquote><p><code>*LazyArithmetic> let x = 1 :: Natural; y = 2 in x - y<br />
*** Exception: Natural: (-)</code></p></blockquote>
<p>We might wish that haskell&#8217;s Numeric type classes were more expressive, allowing for more abstract numeric types. For example it might be more &#8220;haskelly&#8221; for the length function to be defined with the type:</p>
<p><blockquote class="vimblock"><br />
<span class="Comment"></span>&nbsp;<span class="Identifier">length</span>&nbsp;<span class="Statement">::</span>&nbsp;Natural&nbsp;n&nbsp;<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;n<br />
<br /></blockquote></p>
<p>After all we don&#8217;t use integers for boolean values as in C; we have the abstract type <code>Bool</code>. So why return an Int when a Natural type (or class) might be more expressive? The answer of course is that that gets really complicated really fast. </p>
<p>For one approach at making haskell&#8217;s numeric class hierarchy more expressive and flexible, check out the <a href="http://www.haskell.org/haskellwiki/Numeric_Prelude">Numeric Prelude</a>. It&#8217;s <a href="http://hackage.haskell.org/package/numeric-prelude">haddock documentation</a> is very thorough and an interesting read, and you can see the sheer number of design decisions necessary for such an undertaking. </p>
<p>For some other approaches and links, see <a href="http://www.haskell.org/haskellwiki/Libraries_and_tools/Mathematics#Type_class_hierarchies">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>The Definition of Data.List.group</title>
		<link>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/</link>
		<comments>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 16:00:40 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[short]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=312</guid>
		<description><![CDATA[<p>I&#8217;ve been thinking quite a bit lately about a category of functions that are always a bit awkward to define: they involve cases where we would like to traverse a recursive data structure and do something with the data that&#8230; <a href="http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking quite a bit lately about a category of functions that are always a bit awkward to define: they involve cases where we would like to traverse a recursive data structure and do something with the data that we have passed over but which is &#8220;gone now&#8221;.<br />
<span id="more-312"></span><br />
There are many examples of functions like these in the haskell standard libraries: <code><a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#span">span</a></code>, <code><a href="http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#splitAt">splitAt</a></code>, etc.</p>
<p>A function like <code>group</code> is in this category. It&#8217;s conceptually very simple, but defining it actually requires a bit of indirection. Here I&#8217;ve translated the definition from <code>Data.List</code> to use explicit recursion:</p>
<p><blockquote class="vimblock"><br />
<span class="lnr">66 </span><span class="Comment">&gt;</span>&nbsp;group&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;[[a]]<br />
<span class="lnr">67 </span><span class="Comment">&gt;</span>&nbsp;group&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;[]<br />
<span class="lnr">68 </span><span class="Comment">&gt;</span>&nbsp;group&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;group&nbsp;zs<br />
<span class="lnr">69 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;(ys,zs)&nbsp;<span class="Statement">=</span>&nbsp;spanEq&nbsp;as<br />
<span class="lnr">70 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanEq&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;([],&nbsp;[])<br />
<span class="lnr">71 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spanEq&nbsp;(x<span class="Statement">:</span>xs)<br />
<span class="lnr">72 </span><span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;a&nbsp;<span class="Statement">==</span>&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;(ps,qs)&nbsp;<span class="Statement">=</span>&nbsp;spanEq&nbsp;xs&nbsp;<br />
<span class="lnr">73 </span><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="lnr">74 </span><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 />
<span class="lnr">75 </span><br />
<br /></blockquote></p>
<p>I think if I were asked to define this having never seen it, the first thing I would think of would be something using <code>foldl1</code>, which wouldn&#8217;t work.</p>
<p><em><strong>EDIT</strong>:</em> see also <a href="http://coder.bsimmons.name/blog/2010/02/an-alternative-definition-for-datalistgroupby/">an alternative definition for Data.List.groupBy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/02/the-definition-of-datalistgroup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The move-to-front (MTF) Transform</title>
		<link>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/</link>
		<comments>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 13:06:35 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[short]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=265</guid>
		<description><![CDATA[<p>To follow up my last <a href="http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/">post about the Burrows-Wheeler Transform</a>, I decided to implement another simple algorithm which is often used after the BWT to help consolidate localized redundancy in the data before entropy encoding.</p>
<p>The idea behind the&#8230; <a href="http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>To follow up my last <a href="http://coder.bsimmons.name/blog/2009/11/polishing-a-functional-pearl-the-burrows-wheeler-transform/">post about the Burrows-Wheeler Transform</a>, I decided to implement another simple algorithm which is often used after the BWT to help consolidate localized redundancy in the data before entropy encoding.</p>
<p>The idea behind the <a href="http://www.data-compression.info/Algorithms/MTF/index.htm">Move-to-Front algorithm</a> is that we start with some known alphabet (like the list of ASCII characters), and encode our data elements as the <em>index into that alphabet list</em> of each element. The trick is that after each character is encoded, the alphabet list is modified by <strong>moving</strong> the element whose index we just looked up <strong>to the front</strong> of the alphabet.</p>
<p>Here are my implementations of encode and decode:</p>
<p><blockquote class="vimblock"><br>
<span class="PreProc">import</span>&nbsp;Data.List<br>
<br>
<br>
mtf&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Eq</span>&nbsp;a,&nbsp;<span class="Type">Bounded</span>&nbsp;a,&nbsp;<span class="Type">Enum</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Maybe</span>&nbsp;[<span class="Type">Int</span>]<br>
mtf&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">sequence</span>&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;mapAccumL&nbsp;enc&nbsp;[&nbsp;<span class="Identifier">minBound</span><span class="Statement">..</span>&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;enc&nbsp;l&nbsp;x&nbsp;<span class="Statement">=</span>&nbsp;(x<span class="Statement">:</span>delete&nbsp;x&nbsp;l,&nbsp;elemIndex&nbsp;x&nbsp;l)<br>
<br>
<br>
mtfD&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Eq</span>&nbsp;a,&nbsp;<span class="Type">Bounded</span>&nbsp;a,&nbsp;<span class="Type">Enum</span>&nbsp;a)<span class="Statement">=&gt;</span>&nbsp;[<span class="Type">Int</span>]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
mtfD&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">snd</span>&nbsp;<span class="Statement">.</span>&nbsp;mapAccumL&nbsp;dec&nbsp;[&nbsp;<span class="Identifier">minBound</span><span class="Statement">..</span>&nbsp;]<br>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">where</span>&nbsp;dec&nbsp;l&nbsp;i&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;x&nbsp;<span class="Statement">=</span>&nbsp;l&nbsp;<span class="Statement">!!</span>&nbsp;i&nbsp;<br>
&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>delete&nbsp;x&nbsp;l,&nbsp;x)<br>
<br></blockquote></p>
<p>The <code>mapAccumL</code> function is perfect for passing the state of the dictionary list. Another point of interest to mention is the use of <code>minBound</code> to let the function be polymorphic over any type for which there is a defined order and lowest element.</p>
<p>For example, we can do this:</p>
<blockquote><p><strong>*Main></strong> mtf &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;  >>= return . mtfDec :: Maybe String<br />
<em>Just &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;</em></p></blockquote>
<p>or we can decode to Word8 bytes, if we want to get back the ASCII character in that form, just by specifying a different return type:</p>
<blockquote><p><strong>*Main></strong> :m + Data.Word<br />
<strong>*Main Data.Word></strong> mtf &#8220;SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES&#8221;  >>= return . mtfDec :: Maybe [Word8]<br />
<em>Just [83,73,88,46,77,73,88,69,68,46,80,73,88,73,69,83, 46,83,73,70,84,46,83,73,88,84,89,46,80,73,88,73,69,46, 68,85,83,84,46,66,79,88,69,83]</em>
</p></blockquote>
<p>Let me know your thoughts!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/11/the-move-to-front-mtf-transform/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cracking a Lock in Haskell with the De Bruijn sequence, pt. 2</title>
		<link>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/</link>
		<comments>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 22:10:58 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[sequences]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=221</guid>
		<description><![CDATA[<p>For this post I will rework the <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">Prefer One algorithm from<br />
the previous post</a> so that it is much more efficient. We will<br />
add words to a <a href="http://en.wikipedia.org/wiki/Patricia_tree">Patricia Tree</a>-like dictionary as we see them,<br />
passing&#8230; <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>For this post I will rework the <a href="http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-1/">Prefer One algorithm from<br />
the previous post</a> so that it is much more efficient. We will<br />
add words to a <a href="http://en.wikipedia.org/wiki/Patricia_tree">Patricia Tree</a>-like dictionary as we see them,<br />
passing the tree along in the State monad; to check if a new<br />
word has been seen we simply check in the tree, rather than<br />
in the array.</p>
<p>First, a little boilerplate&#8230;</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;Main<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span><br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.Array<br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.List(isInfixOf, tails)<br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Monad.State<br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Arrow<br>
<br></div></p>
<h3>NEW IMPLEMENTATION:</h3>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>In the previous implementation, to check if the word formed<br />
by adding a one has been seen, we had to iterate through each<br />
of the previous bits in the array, checking words.</p>
<p>For example for words of length 3, finding the 7th bit (?)<br />
by checking if 111 has already been seen:</p>
<pre>
        /-----\  ==>  111
0 0 0 1 1 1 (1)...
\----/         000 == 111  No
  \----/       001 == 111  No
    \----/     011 == 111  No
      \----/   111 == 111  Yes, so this bit must be (0)
</pre>
<p>This is extremely inefficient. What we want is to be able to<br />
store all the previous words that we&#8217;ve encountered in an easily-<br />
searchable data structure. </p>
<p>In the example above, we would like the three words that we&#8217;ve<br />
seen to be stored in what might be called a Trie, so that our<br />
search instead looks like the following:</p>
<pre>
       /\
      0  1         1 - in tree, go right
     / \  \
    0   1  1       1 - in tree, go right
   / \   \  \
  0   1   1  1     1 - in tree, we've already seen 111,
                       so the last bit must be 0
</pre>
<p>Our new data structure will look like this:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">data</span>&nbsp;Tree&nbsp;<span class="Statement">=</span>&nbsp;Bs&nbsp;Tree&nbsp;Tree&nbsp;&nbsp;<span class="Comment">-- Bs (zero_bit) (one_bit)</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;X&nbsp;<span class="Comment">-- incomplete word</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;B&nbsp;<span class="Comment">-- final bit of word</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;<span class="Type">Show</span><br>
<br></div></p>
<p>We&#8217;ll need to build a new tree from a list of bits, appending<br />
a final bit (1, except for the initial tree):</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;treeWithFinal1&nbsp;<span class="Statement">=</span>&nbsp;mkTree&nbsp;<span class="Constant">True</span><br>
<span class="Comment">&gt;</span>&nbsp;treeWithFinal0&nbsp;<span class="Statement">=</span>&nbsp;mkTree&nbsp;<span class="Constant">False</span><br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;mkTree&nbsp;<span class="Statement">::</span>&nbsp;Bit&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Bit]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree<br>
<span class="Comment">&gt;</span>&nbsp;mkTree&nbsp;p&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">foldr</span>&nbsp;mkBranch&nbsp;(<span class="Statement">if</span>&nbsp;p&nbsp;<span class="Statement">then</span>&nbsp;Bs&nbsp;X&nbsp;B&nbsp;<span class="Statement">else</span>&nbsp;Bs&nbsp;B&nbsp;X)&nbsp;&nbsp; <br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;mkBranch&nbsp;b&nbsp;<span class="Statement">|</span>&nbsp;b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;Bs&nbsp;X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">--1</span><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;<span class="Statement">|</span>&nbsp;<span class="Identifier">otherwise</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">flip</span>&nbsp;Bs&nbsp;X&nbsp;<span class="Comment">--0</span><br>
<br>
<br></div></p>
<p>Finally, here is our new algorithm. The tree is passed in the<br />
State monad, through the use of mapM. The state monad is a little<br />
tricky sometimes:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;preferOneV2&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;[&nbsp;Bit&nbsp;]<br>
<span class="Comment">&gt;</span>&nbsp;preferOneV2&nbsp;n&nbsp;<span class="Statement">=</span>&nbsp;<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">let</span>&nbsp;upB&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">2</span><span class="Statement">^</span>n<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- the whole bit sequence (one period):</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Identifier">take</span>&nbsp;upB&nbsp;(<span class="Identifier">replicate</span>&nbsp;n&nbsp;<span class="Constant">False</span>&nbsp;<span class="Statement">++</span>&nbsp;bs')<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (wp0<span class="Statement">:</span>wordPrefixes)&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;<span class="Identifier">take</span>&nbsp;(n<span class="Statement">-</span><span class="Constant">1</span>)&nbsp;w&nbsp;<span class="Statement">|</span>&nbsp;w&nbsp;<span class="Statement">&lt;-</span>&nbsp;tails&nbsp;bs&nbsp;]<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- pass our Tree around in the State monad</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state0&nbsp;<span class="Statement">=</span>&nbsp;treeWithFinal0&nbsp;wp0<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- thisBit is partially applied, after which we wrap the</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- function in a State constructor to make our :: m a</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bsM'&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">mapM</span>&nbsp;(State&nbsp;<span class="Statement">.</span>&nbsp;thisBit)&nbsp;wordPrefixes<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (bs',tree)&nbsp;<span class="Statement">=</span>&nbsp;runState&nbsp;bsM' state0<br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- an infinite stream is returned... because I can:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;<span class="Identifier">cycle</span>&nbsp;bs<br>
<br>
<br></div></p>
<p>With the following function, after we apply it to the word we&#8217;re searching<br />
for, it becomes a function :: state -> (val,state), suitable for the<br />
State monad:</p>
<p>Takes a list of the last n-1 Bits (Bools) and traverses a Tree which we&#8217;ve<br />
been using to keep track of the words we&#8217;ve already seen. We fold the Bit<br />
list into the tree. When we get to the endo of the list, we look for a One.<br />
We return the new bit as well as the new Tree:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;<span class="Statement">::</span>&nbsp;[&nbsp;Bit&nbsp;]&nbsp;<span class="Statement">-&gt;</span>&nbsp;Tree&nbsp;<span class="Statement">-&gt;</span>&nbsp;(Bit,&nbsp;Tree)<br>
<br></div></p>
<p>We&#8217;re at a Zero bit,</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;(<span class="Constant">False</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;X&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Constant">True</span>,&nbsp;Bs&nbsp;(treeWithFinal1&nbsp;bs)&nbsp;o)&nbsp;<span class="Comment">-- last bit must be 1</span><br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;(<span class="Constant">False</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Identifier">id</span>&nbsp;<span class="Statement">***</span>&nbsp;<span class="Identifier">flip</span>&nbsp;Bs&nbsp;o)&nbsp;(thisBit&nbsp;bs&nbsp;z)<br>
<br></div></p>
<p>&#8230;a One bit,</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;(<span class="Constant">True</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;z&nbsp;X)&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Constant">True</span>,&nbsp;Bs&nbsp;z&nbsp;(treeWithFinal1&nbsp;bs))&nbsp;<br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;(<span class="Constant">True</span><span class="Statement">:</span>bs)&nbsp;(Bs&nbsp;z&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Identifier">id</span>&nbsp;<span class="Statement">***</span>&nbsp;Bs&nbsp;z)&nbsp;(thisBit&nbsp;bs&nbsp;o)<br>
<br></div></p>
<p>&#8230;or else propose a One for the last bit:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;thisBit&nbsp;[]&nbsp;(Bs&nbsp;_&nbsp;o)&nbsp;<span class="Statement">=</span>&nbsp;(b&nbsp;,&nbsp;(Bs&nbsp;z&nbsp;B))&nbsp;<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- we know that if the One bit has been seen (B) then we must</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- place a zero. we assume then that the Zero bit is (X):</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;(b,&nbsp;z)&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">case</span>&nbsp;o&nbsp;<span class="Statement">of</span>&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; <span class="Comment">-- this bit = 1, Zero branch = nil</span><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; X&nbsp;<span class="Statement">-&gt;</span>&nbsp;(<span class="Constant">True</span>,&nbsp;&nbsp;X)&nbsp;<span class="Comment">-- 1</span><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; <span class="Comment">-- this bit = 0, Zero branch = last word bit</span><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;<span class="Statement">-&gt;</span>&nbsp;(<span class="Constant">False</span>,&nbsp;B)&nbsp;<span class="Comment">-- 0</span><br>
<br>
<br></div></p>
<h3>TEST FUNCTIONS:</h3>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>This code is copied from the previous post:</p>
<p>We use Bool for bits, where False ==> 0, True ==> 1:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;Bit&nbsp;<span class="Statement">=</span>&nbsp;<span class="Type">Bool</span><br>
<br></div></p>
<p>Our garage-door lock model for testing the function:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;Combo&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">=</span>&nbsp;[&nbsp;Bit&nbsp;]<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;Receiver&nbsp;<span class="Statement">=</span>&nbsp;Combo&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">Bool</span><br>
<br></div></p>
<p>True means access granted:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;programReceiver&nbsp;<span class="Statement">::</span>&nbsp;Combo&nbsp;<span class="Statement">-&gt;</span>&nbsp;Receiver<br>
<span class="Comment">&gt;</span>&nbsp;programReceiver&nbsp;<span class="Statement">=</span>&nbsp;isInfixOf&nbsp;<br>
<br></div></p>
<p>Test out our function:</p>
<p><div class="vimblock"><br>
<span class="Comment">&gt;</span>&nbsp;main&nbsp;<span class="Statement">=</span>&nbsp;&nbsp;<span class="Statement">let</span>&nbsp;secretCode&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Constant">True</span>,<span class="Constant">True</span>,<span class="Constant">False</span>,<span class="Constant">False</span>,<span class="Constant">True</span>,<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; <span class="Constant">False</span>,<span class="Constant">True</span>,<span class="Constant">False</span>,<span class="Constant">True</span>,<span class="Constant">True</span>]<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receiver&nbsp;<span class="Statement">=</span>&nbsp;programReceiver&nbsp;secretCode<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; crackingStream&nbsp;<span class="Statement">=</span>&nbsp;preferOneV2&nbsp;<span class="Constant">10</span><br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;<span class="Statement">if</span>&nbsp;receiver&nbsp;crackingStream<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">then</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Constant">&quot;WE'RE IN!&quot;</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">else</span>&nbsp;<span class="Identifier">print</span>&nbsp;<span class="Constant">&quot;...bugs&quot;</span><br>
<span class="Comment">&gt;</span><br>
<br></div></p>
<p>Stay tuned for one more post on these algorithms.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/09/cracking-a-lock-in-haskell-with-the-de-bruijn-sequence-pt-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
