<?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>blog.poucet.org &#187; Uncategorized</title>
	<atom:link href="http://blog.poucet.org/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.poucet.org</link>
	<description>Blogging about technology, functional programming, linux and life in general.</description>
	<lastBuildDate>Sun, 09 Jan 2011 13:19:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Haskell Platform on Mac OSX</title>
		<link>http://blog.poucet.org/2011/01/haskell-platform-on-mac-osx/</link>
		<comments>http://blog.poucet.org/2011/01/haskell-platform-on-mac-osx/#comments</comments>
		<pubDate>Sun, 09 Jan 2011 13:19:36 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.poucet.org/?p=173</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2011/01/haskell-platform-on-mac-osx/&via=poucet&text=Haskell Platform on Mac OSX&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>The other day I was trying to install ghc-core, which requires pcre.</p>
<p>I had previously installed <a href="http://www.macports.org/">macports</a> as this allows you to install a variety of unix applications and tools.  Unfortunately, I just could not get it to work.  After some fiddling with paths to try to get it to find the macports installed libraries (after having port installed pcre), I came up with the following incantation:</p>
<p><code>LIBRARY_PATH=/usr/lib:/opt/local/lib sudo cabal install  --extra-lib-dirs=/opt/local/lib --extra-include-dirs=/opt/local/include ghc-core</code></p>
<p>However, this unfortunately did not work:<br />
<code>Linking dist/build/ghc-core/ghc-core ...<br />
Undefined symbols:<br />
"_iconv_open", referenced from:<br />
_hs_iconv_open in libHSbase-4.2.0.2.a(iconv.o)<br />
"_iconv_close", referenced from:<br />
_hs_iconv_close in libHSbase-4.2.0.2.a(iconv.o)<br />
"_iconv", referenced from:<br />
_hs_iconv in libHSbase-4.2.0.2.a(iconv.o)<br />
ld: symbol(s) not found<br />
collect2: ld returned 1 exit status<br />
cabal: Error: some packages failed to install:<br />
ghc-core-0.5.4 failed during the building phase.<br />
</code></p>
<p>After some Googling, I was finally able to find <a href="http://stackoverflow.com/questions/2726248/ghc-6-12-and-macports/3601842#3601842"> the issue</a></p>
<p>So I decided to completely <a href="http://guide.macports.org/chunked/installing.macports.uninstalling.html">uninstall macports</a>.</p>
<p>As <a href="http://blogs.nonado.net/diamond/">my friend</a> put it on IRC:</p>
<blockquote><p>kormat&gt; unix on osx is a ghetto</p></blockquote>
<p>Fortunately, there is an alternative to macports: <a href="http://mxcl.github.com/homebrew/">Homebrew</a>.</p>
<p>It was a breeze to install:<br />
<code>ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"<br />
sudo brew install pcre</code></p>
<p>After that, cabal installing ghc-core worked as expected =)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2011/01/haskell-platform-on-mac-osx/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Migration</title>
		<link>http://blog.poucet.org/2010/09/migration/</link>
		<comments>http://blog.poucet.org/2010/09/migration/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 13:55:37 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.poucet.org/?p=152</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2010/09/migration/&via=poucet&text=Migration&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>I migrated my linode box from an old version of Ubuntu to a new one.  Unfortunately it was a bit of a pain as a plain migration did not work.  So I had to install a new system and then reset up my blog and copy over the MySQL database.  This is also the reason why this site was down for a day.</p>
<p>I have also imported my old blogs from blogspot.com as I had planned to do once.  You will find that for now they are completely illegible since unfortunately a lot of formatting was lost in the source code.  I&#8217;ll try to fix those, time permitting.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2010/09/migration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up iptables to throttle incoming ssh</title>
		<link>http://blog.poucet.org/2009/11/setting-up-iptables-to-throttle-incoming-ssh/</link>
		<comments>http://blog.poucet.org/2009/11/setting-up-iptables-to-throttle-incoming-ssh/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 22:56:13 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.poucet.org/?p=132</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/11/setting-up-iptables-to-throttle-incoming-ssh/&via=poucet&text=Setting up iptables to throttle incoming ssh&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>So I decided today, since I seem to be getting a lot of ssh attempts to my firewall at home to set up some iptable rules.</p>
<p>It took me quite a while to figure it out, since I needed to set up some modprobe options.</p>
<p>First, I set that I can count up to 250 (I think the maximum is 256) recent ip hits.</p>
<p><code>cat /etc/modprobe.d/options<br />
options ipt_recent ip_pkt_list_tot=250</code></p>
<p>Then I created a firewall script:</p>
<p><code>cat firewall.sh</code></p>
<pre><code>#!/bin/sh
ipt=/sbin/iptables

set -x

if [ -z $1 ] ; then
echo "$0 &lt;public device&gt;"
exit
fi

# Clear rules
$ipt -D INPUT -i $1 -p TCP --dport ssh -m state --state NEW -j "$1"-SSH 2&gt;/dev/null

# Set up an ssh and blacklist chain.
$ipt -F "$1"-SSH 2&gt;/dev/null
$ipt -F "$1"-BLACKLIST 2&gt;/dev/null
$ipt -X "$1"-SSH 2&gt;/dev/null
$ipt -X "$1"-BLACKLIST 2&gt;/dev/null

$ipt -N "$1"-SSH
$ipt -N "$1"-BLACKLIST

# Make sure that we update the recency of the packet, and then drop them.  The timing is controlled by the ssh chain.
$ipt -A "$1"-BLACKLIST -m recent --name BLACKLIST --set
$ipt -A "$1"-BLACKLIST -j DROP

# In the ssh chain, incoming connections from BLACKLIST hosts are dropped.  The timer is restarted everytime we get a packet within 600 s.
$ipt -A "$1"-SSH -m recent --update --name BLACKLIST --seconds 600 --hitcount 1 -j DROP

# Create several counting buckets.
$ipt -A "$1"-SSH -m recent --set --name "$1"-BUCKET1
$ipt -A "$1"-SSH -m recent --set --name "$1"-BUCKET2
$ipt -A "$1"-SSH -m recent --set --name "$1"-BUCKET3
$ipt -A "$1"-SSH -m recent --set --name "$1"-BUCKET4

# Blacklist if:
#   More than 2 connections in 10 seconds
#   More than 14 connections in 120 seconds
#   More than 79 connections in 600 seconds
#   More than 250 connections in 1800 seconds
$ipt -A "$1"-SSH -m recent --update --name "$1"-BUCKET1 --seconds   10 --hitcount   3 -j "$1"-BLACKLIST
$ipt -A "$1"-SSH -m recent --update --name "$1"-BUCKET2 --seconds  120 --hitcount  15 -j "$1"-BLACKLIST
$ipt -A "$1"-SSH -m recent --update --name "$1"-BUCKET3 --seconds  600 --hitcount  80 -j "$1"-BLACKLIST
$ipt -A "$1"-SSH -m recent --update --name "$1"-BUCKET4 --seconds 1800 --hitcount 250 -j "$1"-BLACKLIST

# All other ssh access is allowed.
$ipt -A "$1"-SSH -j ACCEPT

# Allow packets that belong to existing connections.
$ipt -D INPUT -i $1 -m state --state RELATED,ESTABLISHED -j ACCEPT 2&gt;/dev/null
$ipt -A INPUT -i $1 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow all packets from loopback device.
$ipt -D INPUT -i lo -j ACCEPT 2&gt;/dev/null
$ipt -A INPUT -i lo -j ACCEPT

# Redirect all incoming ssh connections to the chain of the same name.
$ipt -A INPUT -i $1 -p TCP --dport ssh -m state --state NEW -j "$1"-SSH

# What remains has no right to continue.
$ipt -D INPUT -i $1 -j DROP 2&gt;/dev/null
$ipt -A INPUT -i $1 -j DROP</code></pre>
<p>Finally, I set it up in my /etc/network/interfaces, that this should be called for my main interface (my public one):<br />
<code>auto eth0<br />
iface eth0 inet dhcp<br />
up firewall.sh eth0</code><br />
I hope this helps anyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/11/setting-up-iptables-to-throttle-incoming-ssh/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>To my family and friends</title>
		<link>http://blog.poucet.org/2009/08/to-my-family-and-friends/</link>
		<comments>http://blog.poucet.org/2009/08/to-my-family-and-friends/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 15:39:49 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.poucet.org/?p=127</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/08/to-my-family-and-friends/&via=poucet&text=To my family and friends&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>I think this is probably one of the best <a href="http://www.xkcd.com">XKCD</a> comics.  I wish I had had this in the past when people or family would ask me questions about computers (usually windows, being an avid Linux user).</p>
<p><a href="http://xkcd.com/627/"><img class="alignnone" title="How geeks perform tech support." src="http://imgs.xkcd.com/comics/tech_support_cheat_sheet.png" alt="" width="732" height="823" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/08/to-my-family-and-friends/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>This blog is obsolete</title>
		<link>http://blog.poucet.org/2009/08/this-blog-is-obsolete/</link>
		<comments>http://blog.poucet.org/2009/08/this-blog-is-obsolete/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 17:33:00 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.poucet.org/2009/08/this-blog-is-obsolete/</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/08/this-blog-is-obsolete/&via=poucet&text=This blog is obsolete&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>It seems I am still getting traffic on this blog.</p>
<p>I have moved my blog to http://blog.poucet.org</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/08/this-blog-is-obsolete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flattening Data.Map</title>
		<link>http://blog.poucet.org/2009/04/flattening-datamap/</link>
		<comments>http://blog.poucet.org/2009/04/flattening-datamap/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 14:22:22 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cpoucet.wordpress.com/?p=120</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/04/flattening-datamap/&via=poucet&text=Flattening Data.Map&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>While at the haskell hackathon, I decided to work on adaptive containers, which is an initiative that had been started by <a href="http://www.cse.unsw.edu.au/~dons/">Don Stewart</a>, to get Data.Map and Data.IntMap more memory compact.  Together with <a href="http://nicolaspouillard.fr/">Nicolas Pouillard(ertai)</a> we tackled this project.  He worked on IntMap while I worked on Map.  You can find the code at: <a href="http://patch-tag.com/repo/adaptive-containers">http://patch-tag.com/repo/adaptive-containers</a>.</p>
<p>The main motivation for these adaptive containers it that it is impossible to flatten (or unpack) small data-types directly into the memory used by the data-constructor, so you end up with extra pointers for each value inside a container (specifically 2 pointers, 1 from the container to the data-type, and then one from the data-type to the unboxed one).</p>
<p><strong>Update</strong>: A <a href="http://vimeo.com/4258084">video was</a> posted where Don Stewart presents the basic concepts and where I briefly present the associative adaptive containers mentioned in this article.</p>
<p>It is very easy to create flattened maps now, all you have to do is instantiate the following typeclass:</p>
<pre><span style="color:green;"><span style="text-decoration:underline;">class</span></span> AdaptMap k a <span style="color:green;"><span style="text-decoration:underline;">where</span></span>
  <span style="color:green;"><span style="text-decoration:underline;">data</span></span> Map k a

  tip <span style="color:red;">::</span> Map k a
  unsafeBin <span style="color:red;">::</span> Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> Map k a
  mapMap <span style="color:red;">::</span> c <span style="color:red;">-&gt;</span> <span style="color:cyan;">(</span>Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> c<span style="color:cyan;">)</span> <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> c
  mapMap2 <span style="color:red;">::</span> <span style="color:cyan;">(</span>AdaptMap k b<span style="color:cyan;">)</span>
          <span style="color:red;">=&gt;</span> c
          <span style="color:red;">-&gt;</span> <span style="color:cyan;">(</span>Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> c<span style="color:cyan;">)</span> <span style="color:blue;">-- Right is Tip</span>
          <span style="color:red;">-&gt;</span> <span style="color:cyan;">(</span>Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> b <span style="color:red;">-&gt;</span> Map k b <span style="color:red;">-&gt;</span> Map k b <span style="color:red;">-&gt;</span> c<span style="color:cyan;">)</span> <span style="color:blue;">-- Left is Tip</span>
          <span style="color:red;">-&gt;</span> <span style="color:cyan;">(</span>Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span> Map k a <span style="color:red;">-&gt;</span>
              Size <span style="color:red;">-&gt;</span> k <span style="color:red;">-&gt;</span> b <span style="color:red;">-&gt;</span> Map k b <span style="color:red;">-&gt;</span> Map k b <span style="color:red;">-&gt;</span> c<span style="color:cyan;">)</span>
          <span style="color:red;">-&gt;</span> Map k a
          <span style="color:red;">-&gt;</span> Map k b
          <span style="color:red;">-&gt;</span> c
  mapMap2 t b1 b2 c t1 t2 <span style="color:red;">=</span> mapMap tip1 bin1 t1
    <span style="color:green;"><span style="text-decoration:underline;">where</span></span> tip1                <span style="color:red;">=</span> mapMap t b2 t2
          bin1 s1 k1 i1 l1 r1 <span style="color:red;">=</span> mapMap tip2 bin2 t2
            <span style="color:green;"><span style="text-decoration:underline;">where</span></span> tip2                <span style="color:red;">=</span> b1 s1 k1 i1 l1 r1
                  bin2 s2 k2 i2 l2 r2 <span style="color:red;">=</span> c s1 k1 i1 l1 r1 s2 k2 i2 l2 r2</pre>
<p>Notice that the case for two tree deconstruction is completely defined based on single tree deconstruction, so you only need to worry about <code>tip</code>, <code>unsafeBin</code> and <code>mapMap</code>.  Also note that this representation assumes you will have an implementation that is similar to the original one.</p>
<p>An example would be:</p>
<pre><span style="color:green;"><span style="text-decoration:underline;">instance</span></span> AdaptMap Int Int <span style="color:green;"><span style="text-decoration:underline;">where</span></span>
  <span style="color:green;"><span style="text-decoration:underline;">data</span></span> Map Int Int  <span style="color:red;">=</span> TipIntInt
                    <span style="color:red;">|</span> BinIntInt
                      <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                      <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int
                      <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int
                      <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int Int<span style="color:cyan;">)</span>
                      <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int Int<span style="color:cyan;">)</span>

  tip                              <span style="color:red;">=</span> TipIntInt
  unsafeBin                        <span style="color:red;">=</span> BinIntInt
  mapMap t b TipIntInt             <span style="color:red;">=</span> t
  mapMap t b <span style="color:cyan;">(</span>BinIntInt s k i l r<span style="color:cyan;">)</span> <span style="color:red;">=</span> b s k i l r</pre>
<p>After we got the basic code working, I thought it would be interesting to flatten nodes inside of Data.Adaptive.Map further, so I created a different instance for Int32 (to get as similar as possible to the original keys and values).  The definition is much hairier:</p>
<pre><span style="color:green;"><span style="text-decoration:underline;">instance</span></span> AdaptMap Int32 Int32 <span style="color:green;"><span style="text-decoration:underline;">where</span></span>
  <span style="color:green;"><span style="text-decoration:underline;">data</span></span> Map Int32 Int32  <span style="color:red;">=</span> TipInt32Int32
                        <span style="color:red;">|</span> BinInt32Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                        <span style="color:red;">|</span> BinTipTipInt32Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                        <span style="color:red;">|</span> BinBinTipInt32Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                        <span style="color:red;">|</span> BinTipBinInt32Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                        <span style="color:red;">|</span> BinBinBinInt32Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Size
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:blue;">{-# UNPACK #-}</span> <span style="color:cyan;">!</span>Int32
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>
                          <span style="color:cyan;">!</span><span style="color:cyan;">(</span>Map Int32 Int32<span style="color:cyan;">)</span>

  tip                              <span style="color:red;">=</span> TipInt32Int32
  unsafeBin s k v TipInt32Int32 TipInt32Int32 <span style="color:red;">=</span> BinTipTipInt32Int32 s k v
  unsafeBin s k v <span style="color:cyan;">(</span>BinInt32Int32 s1 k1 v1 l1 r1<span style="color:cyan;">)</span> TipInt32Int32
    <span style="color:red;">=</span> BinBinTipInt32Int32 s k v s1 k1 v1 l1 r1
  unsafeBin s k v TipInt32Int32 <span style="color:cyan;">(</span>BinInt32Int32 s2 k2 v2 l2 r2<span style="color:cyan;">)</span>
    <span style="color:red;">=</span> BinTipBinInt32Int32 s k v s2 k2 v2 l2 r2
  unsafeBin s k v <span style="color:cyan;">(</span>BinInt32Int32 s1 k1 v1 l1 r1<span style="color:cyan;">)</span> <span style="color:cyan;">(</span>BinInt32Int32 s2 k2 v2 l2 r2<span style="color:cyan;">)</span>
    <span style="color:red;">=</span> BinBinBinInt32Int32 s k v s1 k1 v1 l1 r1 s2 k2 v2 l2 r2
  unsafeBin s k v l r
    <span style="color:red;">=</span> BinInt32Int32 s k v l r

  mapMap t b TipInt32Int32                              <span style="color:red;">=</span> t
  mapMap t b <span style="color:cyan;">(</span>BinInt32Int32 s k v l r<span style="color:cyan;">)</span>                  <span style="color:red;">=</span> b s k v l r
  mapMap t b <span style="color:cyan;">(</span>BinTipTipInt32Int32 s k v<span style="color:cyan;">)</span>                <span style="color:red;">=</span>
    b s k v TipInt32Int32 TipInt32Int32
  mapMap t b <span style="color:cyan;">(</span>BinBinTipInt32Int32 s k v s1 k1 v1 l1 r1<span style="color:cyan;">)</span> <span style="color:red;">=</span>
    b s k v <span style="color:cyan;">(</span>BinInt32Int32 s1 k1 v1 l1 r1<span style="color:cyan;">)</span> TipInt32Int32
  mapMap t b <span style="color:cyan;">(</span>BinTipBinInt32Int32 s k v s2 k2 v2 l2 r2<span style="color:cyan;">)</span> <span style="color:red;">=</span>
    b s k v TipInt32Int32 <span style="color:cyan;">(</span>BinInt32Int32 s2 k2 v2 l2 r2<span style="color:cyan;">)</span>
  mapMap t b <span style="color:cyan;">(</span>BinBinBinInt32Int32 s k v s1 k1 v1 l1 r1 s2 k2 v2 l2 r2<span style="color:cyan;">)</span> <span style="color:red;">=</span>
    b s k v <span style="color:cyan;">(</span>BinInt32Int32 s1 k1 v1 l1 r1<span style="color:cyan;">)</span> <span style="color:cyan;">(</span>BinInt32Int32 s2 k2 v2 l2 r2<span style="color:cyan;">)</span></pre>
<p>The reason for this is that I&#8217;ve read in the past that flattening 3 tree nodes into one can give you very good cache locality.  While you are recreating nodes on deconstruction, these will be cache local anyways, so it should not be that expensive to access the data in these.</p>
<p>To see this in action (apologies about the long data-constructors), the following image is a representation of <code>fromList $ zip [1..100] [1..100]</code>.  While the image is not fully clear, it is clear that the number of nodes used to represent this is much smaller.</p>
<p><img class="alignnone size-full wp-image-121" title="100-nodes" src="http://blog.poucet.org/wp-content/uploads/2009/04/100-nodes.png" alt="100-nodes" width="470" height="287" /></p>
<p>In contrast, the simpler Int version of the same data-structure has many more nodes:</p>
<p><img class="alignnone size-full wp-image-123" title="100-nodes2" src="http://blog.poucet.org/wp-content/uploads/2009/04/100-nodes2.png" alt="100-nodes2" width="470" height="287" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/04/flattening-datamap/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bootstrapping cabal</title>
		<link>http://blog.poucet.org/2009/03/bootstrapping-cabal/</link>
		<comments>http://blog.poucet.org/2009/03/bootstrapping-cabal/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 06:15:15 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cpoucet.wordpress.com/?p=96</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/03/bootstrapping-cabal/&via=poucet&text=Bootstrapping cabal&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>Often I have to install cabal onto a machine where I just have GHC 6.8.2 running.  I&#8217;ve found the following little script quite practical to install the basics.  Once you have that installed, it is very easy to install other haskell packages with cabal.</p>
<pre>#!/bin/bash
#
# Copyright 2009 Christophe Poucet. All Rights Reserved.
# Author: &lt;christophe (dot) poucet (at) gmail (dot) com&gt; (Christophe Poucet)
# License: BSD3

webroot=http://hackage.haskell.org/packages/archive

install_package() {
  local name=$1
  local version=$2

  wget $webroot/$name/$version/$name-$version.tar.gz
  tar xvzf $name-$version.tar.gz
  cd $name-$version
  runghc Setup configure
  runghc Setup build
  sudo runghc Setup install
  cd ..
  rm -rf $name-$version
  rm -f $name-$version.tar.gz
}

install_package mtl 1.1.0.2
install_package parsec 3.0.0
install_package network 2.2.0.1
install_package HTTP 4000.0.4
install_package zlib 0.5.0.0
install_package Cabal 1.6.0.2
install_package cabal-install 0.6.2</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/03/bootstrapping-cabal/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Staying with the times&#8230; (?)</title>
		<link>http://blog.poucet.org/2009/02/staying-with-the-times/</link>
		<comments>http://blog.poucet.org/2009/02/staying-with-the-times/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 15:16:49 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cpoucet.wordpress.com/?p=88</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/02/staying-with-the-times/&via=poucet&text=Staying with the times... (?)&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>I&#8217;ve decided to try out twittering.  I know that I&#8217;m seriously lagging on the hype-wave, but I think it might be a nice way to share links that I find interesting.  I have delicious too, but it is not as conversational.  I&#8217;ve also had a friendfeed for a while, so I&#8217;ve linked all my services together there:</p>
<p>http://friendfeed.com/poucet</p>
<p>http://twitter.com/poucet</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/02/staying-with-the-times/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Imported from Blogger</title>
		<link>http://blog.poucet.org/2009/02/imported-from-blogger/</link>
		<comments>http://blog.poucet.org/2009/02/imported-from-blogger/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 12:39:38 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cpoucet.wordpress.com/?p=82</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/02/imported-from-blogger/&via=poucet&text=Imported from Blogger&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>I have just imported all my old blogs from http://notvincenz.blogspot.com, randomly sampling one entry, I noticed that some of the blogs need to be reeditted a bit.  If you happen to notice any broken blogs, please ping me so I can fix it.</p>
<p>Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/02/imported-from-blogger/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fibonacci in the Type System</title>
		<link>http://blog.poucet.org/2009/02/fibonacci-in-the-type-system/</link>
		<comments>http://blog.poucet.org/2009/02/fibonacci-in-the-type-system/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 12:27:27 +0000</pubDate>
		<dc:creator>poucet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cpoucet.wordpress.com/?p=30</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://blog.poucet.org/2009/02/fibonacci-in-the-type-system/&via=poucet&text=Fibonacci in the Type System&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><p>I thought I would share an old piece of code that I&#8217;ve had lying around for a while.  Basically, it calculates Fibonacci numbers in the type system:</p>
<pre>
{-# LANGUAGE EmptyDataDecls, MultiParamTypeClasses,
    FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}
module Fibonacci where

data Nat
data S a = S a
class Numeral a where
value :: a -&gt; Integer

prev :: S a -&gt; a
prev = undefined

instance Numeral Nat where
value _ = 0

instance (Numeral a) =&gt; Numeral (S a) where
value x = 1 + (value . prev $ x)

class Add a b c | a b -&gt; c where
add :: a -&gt; b -&gt; c

instance Add Nat b b where
add = undefined

instance Add a b c =&gt; Add (S a) b (S c) where
add = undefined

class Fib a b | a -&gt; b where
fib :: a -&gt; b

instance Fib Nat Nat where
fib = undefined

instance Fib (S Nat) (S Nat) where
fib = undefined

instance (Fib (S a) b, Fib a c, Add b c d) =&gt; Fib (S (S a)) d where
fib x = undefined

main = print . value . fib . S . S . S . S . S
                           . S . S . S . S $ (undefined :: Nat)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.poucet.org/2009/02/fibonacci-in-the-type-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

