<?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; Tree</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/tree/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>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>
		<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>Huffman Coding</title>
		<link>http://coder.bsimmons.name/blog/2009/05/huffman-coding/</link>
		<comments>http://coder.bsimmons.name/blog/2009/05/huffman-coding/#comments</comments>
		<pubDate>Sun, 31 May 2009 00:35:54 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=172</guid>
		<description><![CDATA[<p><em>This is the second of probably three posts (the first was on <a href="http://coder.bsimmons.name/blog/2009/05/run-length-encoding/">run-length encoding in Haskell</a>) inspired by Thomas Guest&#8217;s interesting <a href="http://wordaligned.org/articles/deflate-runlength-encoding-but-better">article on the Deflate algorithm</a>.  This is also my first post in literate haskell. Please post any</em>&#8230; <a href="http://coder.bsimmons.name/blog/2009/05/huffman-coding/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>This is the second of probably three posts (the first was on <a href="http://coder.bsimmons.name/blog/2009/05/run-length-encoding/">run-length encoding in Haskell</a>) inspired by Thomas Guest&#8217;s interesting <a href="http://wordaligned.org/articles/deflate-runlength-encoding-but-better">article on the Deflate algorithm</a>.  This is also my first post in literate haskell. Please post any improvements to the code if you have them!</em><br />
<em><br />
For a refreshingly readable introduction to <a href="http://en.wikipedia.org/wiki/Huffman_coding">Huffman Coding</a> and the Deflate algorithm, <a href="http://www.zlib.net/feldspar.html">have a look at this short explanation by Antaeus Feldspar</a>. </em></p>
<p><div class="vimblock"><br>
First some boilerplate...<br>
<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">module</span>&nbsp;Huffman<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.List (sort, insert)<br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;<span class="PreProc">qualified</span>&nbsp;Data.Map <span class="PreProc">as</span>&nbsp;M<br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Data.Function (on)<br>
<span class="Comment">&gt;</span>&nbsp;<span class="PreProc">import</span>&nbsp;Control.Arrow (second)<br>
<br>
We make an abstract datatype for binary digits. I wonder if this would <br>
be a nice (but slow?) way of working with binary IO. There doesn't seem <br>
to be a package on Hackage for this<br>
<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">data</span>&nbsp;Bit&nbsp;<span class="Statement">=</span>&nbsp;O&nbsp;<span class="Statement">|</span>&nbsp;I<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">deriving</span>&nbsp;(<span class="Type">Show</span>,&nbsp;<span class="Type">Ord</span>,&nbsp;<span class="Type">Eq</span>)<br>
<br>
we define a simple binary tree useful for decoding the encoded binary <br>
stream. the simple algorithm for assigning codes to our symbols <br>
produces this tree. A completed tree for some text containing only <br>
three letter might look like this:<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;/\&nbsp;&nbsp;&nbsp;&nbsp;1<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /\ A&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp;B<br>
<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">data</span>&nbsp;HTree&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;Branch&nbsp;{zer&nbsp;<span class="Statement">::</span>&nbsp;(HTree&nbsp;a),&nbsp;one&nbsp;<span class="Statement">::</span>&nbsp;(HTree&nbsp;a),<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;wt&nbsp;&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;}<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">|</span>&nbsp;Leaf&nbsp;{symb&nbsp;<span class="Statement">::</span>&nbsp;a,&nbsp;&nbsp;wt&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Int</span>&nbsp;}<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&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>
maps from &lt;Symbol&gt; to &lt;Binary Code&gt;, we create this from the HTree <br>
built from the list of weighted symbols. the HTree can't be used for<br>
encoding.<br>
<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">type</span>&nbsp;CodeDict&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;M.Map&nbsp;a&nbsp;[Bit]<br>
<br>
Now some instance declarations so that we know how to order (by weight):<br>
<br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">instance</span>&nbsp;<span class="Type">Ord</span>&nbsp;(HTree&nbsp;a)&nbsp;<span class="Type">where</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Identifier">compare</span>&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">compare</span>&nbsp;<span class="Statement">`on`</span>&nbsp;wt<br>
<span class="Comment">&gt;</span><br>
<span class="Comment">&gt;</span>&nbsp;<span class="Type">instance</span>&nbsp;<span class="Type">Eq</span>&nbsp;(HTree&nbsp;a)&nbsp;<span class="Type">where</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; (<span class="Statement">==</span>)&nbsp;<span class="Statement">=</span>&nbsp;(<span class="Statement">==</span>)&nbsp;<span class="Statement">`on`</span>&nbsp;wt<br>
<br>
<br>
our function for merging two branches which we use to build the HTree <br>
from the list of symbols and their corresponding weights. no point in <br>
defining a Monoid instance, but we'll tip our hat to it:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;mappend&nbsp;t1&nbsp;t2&nbsp;<span class="Statement">=</span>&nbsp;Branch&nbsp;t1&nbsp;t2&nbsp;(wt&nbsp;t1&nbsp;<span class="Statement">+</span>&nbsp;wt&nbsp;t2)<br>
<br>
<br>
<h2>    BULDING THE CODING TREES</h3><br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
We assign codes to our weighted symbols using a simple algorithm<br>
which takes the trees (initially Leaves) with the lowest weights <br>
and combines them (and their weights) and inserts them back into <br>
the list until they have been combined into a single tree:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;buildDecTree&nbsp;<span class="Statement">::</span>&nbsp;[(a,<span class="Type">Int</span>)]&nbsp;<span class="Statement">-&gt;</span>&nbsp;HTree&nbsp;a<br>
<span class="Comment">&gt;</span>&nbsp;buildDecTree&nbsp;<span class="Statement">=</span>&nbsp;build&nbsp;<span class="Statement">.</span>&nbsp;sort&nbsp;<span class="Statement">.</span>&nbsp;<span class="Identifier">map</span>&nbsp;(<span class="Identifier">uncurry</span>&nbsp;Leaf)<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;build&nbsp;(t<span class="Statement">:</span>[])&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;t<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; build&nbsp;(t1<span class="Statement">:</span>t2<span class="Statement">:</span>ts)&nbsp;<span class="Statement">=</span>&nbsp;build&nbsp;<span class="Statement">$</span>&nbsp;insert&nbsp;(t1&nbsp;<span class="Statement">`mappend`</span>&nbsp;t2)&nbsp;ts<br>
<br>
<br>
now convert the binary tree representation to a dictionary form for<br>
encoding. we decompose the tree into a list from the top down, mapping<br>
either a 1 or 0 over the flattened children. a little confusing:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;buildEncDict&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Ord</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;HTree&nbsp;a&nbsp;<span class="Statement">-&gt;</span>&nbsp;CodeDict&nbsp;a<br>
<span class="Comment">&gt;</span>&nbsp;buildEncDict&nbsp;<span class="Statement">=</span>&nbsp;M.fromList&nbsp;<span class="Statement">.</span>&nbsp;build&nbsp;<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;build&nbsp;(Leaf&nbsp;t&nbsp;_)&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">=</span>&nbsp;(t,[])&nbsp;<span class="Statement">:</span>&nbsp;[]<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; build&nbsp;(Branch&nbsp;a&nbsp;b&nbsp;_)&nbsp;<span class="Statement">=</span>&nbsp;mapBit&nbsp;O&nbsp;a&nbsp;<span class="Statement">++</span>&nbsp;mapBit&nbsp;I&nbsp;b<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- build up the codes in the snd of each Leaf's tuple:</span><br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mapBit&nbsp;b&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">map</span>&nbsp;(second&nbsp;(b<span class="Statement">:</span>))&nbsp;<span class="Statement">.</span>&nbsp;build<br>
<br>
<br>
<h2>    (EN/DE)CODING FUNCTIONS</h3><br>
<br>
To encode a list of symbols for which we've generated an HTree, we just<br>
map over it, looking up it's code in our Map dictionary:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;encode&nbsp;<span class="Statement">::</span>&nbsp;(<span class="Type">Ord</span>&nbsp;a)&nbsp;<span class="Statement">=&gt;</span>&nbsp;CodeDict&nbsp;a&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Bit]<br>
<span class="Comment">&gt;</span>&nbsp;encode&nbsp;d&nbsp;<span class="Statement">=</span>&nbsp;<span class="Identifier">concatMap</span>&nbsp;(d&nbsp;<span class="Statement">M.!</span>)<br>
<br>
<br>
To decode we simply read a Bit at a time from the input, at the same time<br>
traversing the HTree (going left when we encounter a zero, and vice versa).<br>
When we hit a Leaf (the end of a code) we return the symbol and go onto <br>
the next bit from the top of the HTree once again.<br>
<br>
<span class="Comment">&gt;</span>&nbsp;decode&nbsp;<span class="Statement">::</span>&nbsp;HTree&nbsp;a&nbsp;<span class="Statement">-&gt;</span>&nbsp;[Bit]&nbsp;<span class="Statement">-&gt;</span>&nbsp;[a]<br>
<span class="Comment">&gt;</span>&nbsp;decode&nbsp;t&nbsp;[]&nbsp;<span class="Statement">=</span>&nbsp;[]<br>
<span class="Comment">&gt;</span>&nbsp;decode&nbsp;t&nbsp;bs&nbsp;<span class="Statement">=</span>&nbsp;dec&nbsp;bs&nbsp;t<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">where</span>&nbsp;dec&nbsp;bs' (Leaf&nbsp;x&nbsp;_)&nbsp;<span class="Statement">=</span>&nbsp;x&nbsp;<span class="Statement">:</span>&nbsp;decode&nbsp;t&nbsp;bs'<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dec&nbsp;(O<span class="Statement">:</span>bs')&nbsp;(Branch&nbsp;l&nbsp;_&nbsp;_)&nbsp;<span class="Statement">=</span>&nbsp;dec&nbsp;bs' l&nbsp;<br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dec&nbsp;(I<span class="Statement">:</span>bs')&nbsp;(Branch&nbsp;_&nbsp;r&nbsp;_)&nbsp;<span class="Statement">=</span>&nbsp;dec&nbsp;bs' r&nbsp;<br>
<br>
<br>
<br></div></p>
<p><strong>UPDATE</strong>: <em>I scrapped and re-did this section. Should be a little better now.:</em></p>
<p><div class="vimblock"><br>
<h2>USAGE EXAMPLES</h2><br>
<br>
I realize I need a more compelling example and some explanation. First,<br>
imagine we want to encode into binary the following phrase:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;phrase&nbsp;<span class="Statement">=</span>&nbsp;<span class="Constant">&quot;twenty bytes of text&quot;</span><br>
<br>
we could represent it in ASCII but that would be wasteful of space, using<br>
a whole byte per character when we are using only ten of the 256 possible<br>
codes in the ASCII character set. <br>
<br>
So we generate a list of the characters to encode along with their <br>
frequencies (symbols with higher frequencies will be given shorter<br>
prefix codes, saving space!):<br>
<br>
<span class="Comment">&gt;</span>&nbsp;huffmanTree' <span class="Statement">=</span>&nbsp;buildDecTree&nbsp;[(<span class="Constant">'t'</span>,<span class="Constant">5</span>),(<span class="Constant">'e'</span>,<span class="Constant">3</span>),(<span class="Constant">'y'</span>,<span class="Constant">2</span>),(<span class="Constant">'w'</span>,<span class="Constant">1</span>),(<span class="Constant">'n'</span>,<span class="Constant">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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="Constant">'b'</span>,<span class="Constant">1</span>),(<span class="Constant">'s'</span>,<span class="Constant">1</span>),(<span class="Constant">'o'</span>,<span class="Constant">1</span>),(<span class="Constant">'f'</span>,<span class="Constant">1</span>),(<span class="Constant">'x'</span>,<span class="Constant">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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="Constant">' '</span>,<span class="Constant">3</span>)]<br>
<br>
...and encode it using the dictionary built from the code tree we just<br>
built:<br>
<br>
<span class="Comment">&gt;</span>&nbsp;encodedPhrase&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">let</span>&nbsp;dict&nbsp;<span class="Statement">=</span>&nbsp;buildEncDict&nbsp;huffmanTree' <br>
<span class="Comment">&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">in</span>&nbsp;encode&nbsp;dict&nbsp;phrase<br>
<br>
This yields the following binary stream of 8 bits (vs. 20 if we had used <br>
ASCII encoding):<br>
<br>
[I,O,O,O,I,O,I,I, O,O,O,I,I,I,O,O, I,O,I,I,I,O,O,O, O,O,I,O,I,O,I,I,<br>
&nbsp;O,O,O,O,I,I,I,I, O,I,I,I,O,O,I,I, I,I,I,I,I,I,O,I, I,O,O,I,I,O,I,O]<br>
<br>
Of course we have to encode instructions to build our tree along with the <br>
above message.<br>
<br></div></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/05/huffman-coding/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>directory-tree module released</title>
		<link>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/</link>
		<comments>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/#comments</comments>
		<pubDate>Sat, 09 May 2009 16:33:12 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=148</guid>
		<description><![CDATA[<p>I&#8217;ve released my first package, <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree">up now on hackage</a> (haddock docs should be generated soon). The module provides a simple data structure that mirrors a directory tree, and some useful functions for doing IO on directories of files. You&#8230; <a href="http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released my first package, <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree">up now on hackage</a> (haddock docs should be generated soon). The module provides a simple data structure that mirrors a directory tree, and some useful functions for doing IO on directories of files. You can <a href="http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/">read more about it here</a>.</p>
<p>It&#8217;s very likely there are some bugs, especially related to cross platform issues with file names and paths. The module is also fairly bare, so please send me any requests for functionality that I haven&#8217;t thought of, as well as any bugs you might find. </p>
<p>You can install it with:</p>
<blockquote><p>$ cabal install directory-tree</p></blockquote>
<p>And get the source with:</p>
<blockquote><p>$ darcs get http://coder.bsimmons.name/code/DirectoryTree/</p></blockquote>
<p>I hope this is useful to someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>a DirectoryTree module and some examples</title>
		<link>http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/</link>
		<comments>http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 03:47:10 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=140</guid>
		<description><![CDATA[<p>UPDATE: <em>I&#8217;ve just released this as my first package on hackage. You can read more and write any comments <a href="http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/">here</a>.</em></p>
<p>I just put together a library that provides a simple tree data structure to represent the structure of files&#8230; <a href="http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>UPDATE: <em>I&#8217;ve just released this as my first package on hackage. You can read more and write any comments <a href="http://coder.bsimmons.name/blog/2009/05/directory-tree-module-released/">here</a>.</em></p>
<p>I just put together a library that provides a simple tree data structure to represent the structure of files and directories in the OS. It provides some simple IO functions like <code>readDirectory</code> (analogous to <code>readFile</code>) which &#8220;opens&#8221; a directory, returning a DirTree of Strings in the IO monad. </p>
<p>The nice thing is that by defining a simple instance for <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html">Traversable</a> (and the default instances for Foldable and Functor that we get for free) we get a whole array of nice functions which we can apply to directory structures! For example, we can combine all the text in a directory of files with:</p>
<p><blockquote class="vimblock"><br>
combineFiles&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">FilePath</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Type">IO</span>&nbsp;[<span class="Type">Char</span>]<br>
combineFiles&nbsp;d&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span>&nbsp;(_&nbsp;<span class="Statement">:/</span>&nbsp;t)&nbsp;<span class="Statement">&lt;-</span>&nbsp;readDirectory&nbsp;d<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">return</span>&nbsp;<span class="Statement">$</span>&nbsp;F.foldr1&nbsp;(<span class="Statement">++</span>)&nbsp;t<br>
<br></blockquote></p>
<p>(the <code>(_:/t)</code> portion ignores the base directory returned). The <code>DirTree</code> type also includes a constructor for handling failures. Here is the type definition:</p>
<p><blockquote class="vimblock"><br>
<span class="Type">data</span>&nbsp;DirTree&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;Dir&nbsp;{&nbsp;name&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">::</span>&nbsp;FileName,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contents&nbsp;<span class="Statement">::</span>&nbsp;[DirTree&nbsp;a]&nbsp;&nbsp;}&nbsp;<span class="Comment">--files + directories</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;File&nbsp;{&nbsp;name&nbsp;<span class="Statement">::</span>&nbsp;FileName,<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;file&nbsp;<span class="Statement">::</span>&nbsp;a&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Statement">|</span>&nbsp;Failed&nbsp;{&nbsp;name&nbsp;<span class="Statement">::</span>&nbsp;FileName,<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;err&nbsp;&nbsp;<span class="Statement">::</span>&nbsp;Exception&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">deriving</span>&nbsp;(<span class="Type">Show</span>,&nbsp;<span class="Type">Eq</span>)<br>
<br></blockquote></p>
<p>I have created a <a href="http://coder.bsimmons.name/code/DirectoryTree/examples.hs">file with three examples</a>: </p>
<ol>
<li>in the first we simulate the command <code>darcs initialize</code> to illustrate creating a directory of files by hand, and writing it to disk.</li>
<li>second, we show combining several different directories from around the filesystem and assembling the into a new tree structure.</li>
<li>lastly, we use our <code>readDirectoryWith</code> (with Data.ByteString.readFile), and our Foldable instance to hash all the files in a directory structure (with Thomas DuBuisson&#8217;s <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pureMD5">pureMD5</a> package) and compare it to the hash of a different directory to see if the contents match exactly</li>
</ol>
<p>There are probably bugs, and there are many useful functions I can think of to add if people think this is useful. I would be interested in hearing your thoughts on the interface, on any functionality you would like added, and anything else!</p>
<p>You can get the module and examples.hs with:</p>
<blockquote><p>
$ darcs get http://coder.bsimmons.name/code/DirectoryTree/</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2009/04/a-directorytree-module-and-some-examples/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
