<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Enter the void *</title>
        <link>http://blog.emillon.org</link>
        <description><![CDATA[Yet another random hacker]]></description>
        <atom:link href="http://blog.emillon.org/feeds/life.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Thu, 18 Oct 2012 00:00:00 UT</lastBuildDate>
        <item>
    <title>Comonadic Life</title>
    <link>http://blog.emillon.org/posts/2012-10-18-comonadic-life.html</link>
    <description><![CDATA[<h2 id="of-monads-and-comonads">Of monads and comonads</h2>
<p>This post is written in <a href="http://www.haskell.org/haskellwiki/Literate_programming">Literate Haskell</a>. This means that you can copy it into
a <code>.lhs</code> file<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> and run it through a Haskell compiler or interpreter.</p>
<p>Today we’ll talk about…</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Comonad</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad</span></span></code></pre></div>
<p>Comonads ! They are the categoric dual of monads, which means that the type
signatures of comonadic functions look like monadic functions, but with the
arrow reversed. I am not an expert in category theory, so I won’t go further.</p>
<p>I will use the following typeclass for comonads : it’s from <a href="http://comonad.com">Edward Kmett</a>’s
<a href="http://hackage.haskell.org/package/comonad-3.0.0.2/docs/Control-Comonad.html">comonad package</a> (split from the infamous <a href="http://hackage.haskell.org/package/category-extras-1.0.2">category-extras package</a>).</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> w <span class="ot">=&gt;</span> <span class="dt">Comonad</span> w <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  extract ::</span> w a <span class="ot">-&gt;</span> a</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  extend ::</span> (w a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> w a <span class="ot">-&gt;</span> w b</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  duplicate ::</span> w a <span class="ot">-&gt;</span> w (w a)</span></code></pre></div>
<p><code>extend</code> or <code>duplicate</code> are optional, as one can be written in terms of the
other one. The Monad typeclass, for reference, can be described as<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> :</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  return ::</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (=&lt;&lt;) ::</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  join ::</span> m (m a) <span class="ot">-&gt;</span> m a</span></code></pre></div>
<p>The duality is quite easy to see : <code>extract</code> is the dual of <code>return</code>, <code>extend</code>
the one of <code>(=&lt;&lt;)</code> and <code>duplicate</code> the one of <code>join</code>.</p>
<p>So what are comonads good for ?</p>
<p>I stumbled upon <a href="http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-is.html">an article</a> which explains that they can be
used for computations which depend on some local environment, like <a href="http://en.wikipedia.org/wiki/Cellular_automaton">cellular
automata</a>. Comments ask whether it’s possible to generalize to higher
dimensions, which I will do by implementing <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s Game of Life</a> in a
comonadic way.</p>
<h2 id="list-zippers">List Zippers</h2>
<p>List zippers are a fantastic data structure, allowing O(1) edits at a “cursor”.
Moving the cursor element to element is O(1) too. This makes it a very nice data
structure when your edits are local (say, in a text editor). You can learn more
about zippers in general in this <a href="http://blog.ezyang.com/2010/04/you-could-have-invented-zippers/">post from Edward Z Yang</a>. The seminal paper is
of course <a href="http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf">Huet’s article</a>.</p>
<p>A list zipper is composed of a cursor and two lists.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ListZipper</span> a <span class="ot">=</span> <span class="dt">LZ</span> [a] a [a]</span></code></pre></div>
<p>To go in a direction, you pick the head of a list, set it as your cursor, and
push the cursor on top of the other list. We assume that we will only infinte
lists, so this operation can not fail. This assumption is reasonnable especially
in the context of cellular automata<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">listLeft ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>listLeft (<span class="dt">LZ</span> (l<span class="op">:</span>ls) x rs) <span class="ot">=</span> <span class="dt">LZ</span> ls l (x<span class="op">:</span>rs)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>listLeft _ <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;listLeft&quot;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ot">listRight ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>listRight (<span class="dt">LZ</span> ls x (r<span class="op">:</span>rs)) <span class="ot">=</span> <span class="dt">LZ</span> (x<span class="op">:</span>ls) r rs</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>listRight _ <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;listRight&quot;</span></span></code></pre></div>
<p>Reading and writing on a list zipper at the cursor is straightforward :</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">listRead ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>listRead (<span class="dt">LZ</span> _ x _) <span class="ot">=</span> x</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ot">listWrite ::</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> a</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>listWrite x (<span class="dt">LZ</span> ls _ rs) <span class="ot">=</span> <span class="dt">LZ</span> ls x rs</span></code></pre></div>
<p>We can also define a function to convert a list zipper to a list, for example
for printing. As it’s infinite on both sizes, it’s not possible to convert it to
the whole list, so we have to pass a size parameter.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">ListZipper</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>toList (<span class="dt">LZ</span> ls x rs) n <span class="ot">=</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">reverse</span> (<span class="fu">take</span> n ls) <span class="op">++</span> [x] <span class="op">++</span> <span class="fu">take</span> n rs</span></code></pre></div>
<p>We can easily define a <code>Functor</code> instance for <code>ListZipper</code>. To apply a function
on whole zipper, we apply it to the cursor and map it on the two lists :</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">ListZipper</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">LZ</span> ls x rs) <span class="ot">=</span> <span class="dt">LZ</span> (<span class="fu">map</span> f ls) (f x) (<span class="fu">map</span> f rs)</span></code></pre></div>
<p>Time for the <code>Comonad</code> instance. The <code>extract</code> method returns an element from
the structure : we can pick the one at the cursor.</p>
<p><code>duplicate</code> is a bit harder to grasp. From a list zipper, we have to build a
list zipper of list zippers. The signification behind this (confirmed by the
comonad laws that every instance has to fulfill) is that moving inside the
duplicated structure returns the original structure, altered by the same
move : for example, <code>listRead (listLeft (duplicate z)) == listLeft z</code>.</p>
<p>This means that at the cursor of the duplicated structure, there is the original
structure <code>z</code>. And the left list is composed of <code>listLeft z</code>, <code>listLeft (listLeft z)</code>, <code>listLeft (listLeft (listLeft z))</code>, etc (same goes for the right
list).</p>
<p>The following function applies repeatedly two movement functions on each side of
the zipper (its type is more generic than needed for this specific case but
we’ll instanciate <code>z</code> with something other than <code>ListZipper</code> in the next
section).</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">genericMove ::</span> (z a <span class="ot">-&gt;</span> z a)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> (z a <span class="ot">-&gt;</span> z a)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> z a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (z a)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>genericMove a b z <span class="ot">=</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LZ</span> (iterate&#39; a z) z (iterate&#39; b z)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="ot">iterate&#39; ::</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>iterate&#39; f <span class="ot">=</span> <span class="fu">tail</span> <span class="op">.</span> <span class="fu">iterate</span> f</span></code></pre></div>
<p>And finally we can implement the instance.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">ListZipper</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  extract <span class="ot">=</span> listRead</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  duplicate <span class="ot">=</span> genericMove listLeft listRight</span></code></pre></div>
<p>Using this comonad instance we can already implement 1D cellular automata, as
explained in the <a href="http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-is.html">sigfpe article</a>. Let’s see how they can be extended to 2D
automata.</p>
<h2 id="plane-zippers">Plane zippers</h2>
<p>Let’s generalize list zippers to plane zippers, which are cursors on a plane
of cells. We will implement them using a list zipper of list zippers.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Z</span> a <span class="ot">=</span> <span class="dt">Z</span> (<span class="dt">ListZipper</span> (<span class="dt">ListZipper</span> a))</span></code></pre></div>
<p>We start by defining move functions. As a convention, the external list will
hold lines : to move up and down, we will really move left and right at the root
level.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">up ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>up (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (listLeft z)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ot">down ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>down (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (listRight z)</span></code></pre></div>
<p>For left and right, it is necessary to alter every line, using the <code>Functor</code>
instance.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">left ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>left (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> listLeft z)</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="ot">right ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>right (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> listRight z)</span></code></pre></div>
<p>Finally, editing is quite straightforward : reading is direct (first read the line,
then the cursor) ; and in order to write, it is necessary to fetch the current
line, write to it and write the new line.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zRead ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>zRead (<span class="dt">Z</span> z) <span class="ot">=</span> listRead <span class="op">$</span> listRead z</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="ot">zWrite ::</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>zWrite x (<span class="dt">Z</span> z) <span class="ot">=</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> <span class="op">$</span> listWrite newLine z</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>      newLine <span class="ot">=</span> listWrite x oldLine</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>      oldLine <span class="ot">=</span> listRead z</span></code></pre></div>
<p>Time for algebra. Let’s define a <code>Functor</code> instance : applying a function
everywhere can be achieved by applying it on every line.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Z</span> z) <span class="ot">=</span> <span class="dt">Z</span> (<span class="fu">fmap</span> (<span class="fu">fmap</span> f) z)</span></code></pre></div>
<p>The idea behind the <code>Comonad</code> instance for <code>Z</code> is the same that the <code>ListZipper</code>
one : moving “up” in the structure (really, “left” at the root level) returns
the original structure moved in this direction.</p>
<p>We will reuse the <code>genericMove</code> defined earlier in order to build list zippers
that describe movements in the two axes<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">horizontal ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (<span class="dt">Z</span> a)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>horizontal <span class="ot">=</span> genericMove left right</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">vertical ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">ListZipper</span> (<span class="dt">Z</span> a)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>vertical <span class="ot">=</span> genericMove up down</span></code></pre></div>
<p>This is enough to define the instance.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  extract <span class="ot">=</span> zRead</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  duplicate z <span class="ot">=</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Z</span> <span class="op">$</span> <span class="fu">fmap</span> horizontal <span class="op">$</span> vertical z</span></code></pre></div>
<h2 id="conways-comonadic-game-of-life">Conway’s (comonadic) Game of Life</h2>
<p>Let’s define a neighbourhood function. Here, directions are moves on a plane
zipper. Neighbours are : horizontal moves, vertical moves and their
compositions (<code>liftM2 (.)</code>)<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">neighbours ::</span> [<span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a]</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>neighbours <span class="ot">=</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  horiz <span class="op">++</span> vert <span class="op">++</span> liftM2 (<span class="op">.</span>) horiz vert</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>      horiz <span class="ot">=</span> [left, right]</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>      vert  <span class="ot">=</span> [up, down]</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="ot">aliveNeighbours ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>aliveNeighbours z <span class="ot">=</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>  card <span class="op">$</span> <span class="fu">map</span> (\ dir <span class="ot">-&gt;</span> extract <span class="op">$</span> dir z) neighbours</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="ot">card ::</span> [<span class="dt">Bool</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>card <span class="ot">=</span> <span class="fu">length</span> <span class="op">.</span> <span class="fu">filter</span> (<span class="op">==</span><span class="dt">True</span>)</span></code></pre></div>
<p>The core rule of the game fits in the following function : if two neighbours are
alive, return the previous state ; if three neighbours are alive, a new cell is
born, and any other count causes the cell to die (of under-population or
overcrowding).</p>
<p>It is remarkable that its type is the dual of that of a Kleisli arrow (<code>a -&gt; m b</code>).</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rule ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>rule z <span class="ot">=</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">case</span> aliveNeighbours z <span class="kw">of</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span> <span class="ot">-&gt;</span> extract z</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">-&gt;</span> <span class="dt">False</span></span></code></pre></div>
<p>And then the comonadic magic happens with the use of <code>extend</code> :</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evolve ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Z</span> <span class="dt">Bool</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>evolve <span class="ot">=</span> extend rule</span></code></pre></div>
<p><code>evolve</code> is our main transition function between world states, and yet it’s only
defined in terms of the local transition function !</p>
<p>Let’s define a small printer to see what’s going on.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dispLine ::</span> <span class="dt">ListZipper</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>dispLine z <span class="ot">=</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">map</span> dispC <span class="op">$</span> toList z <span class="dv">6</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      dispC <span class="dt">True</span>  <span class="ot">=</span> <span class="ch">&#39;*&#39;</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      dispC <span class="dt">False</span> <span class="ot">=</span> <span class="ch">&#39; &#39;</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="ot">disp ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>disp (<span class="dt">Z</span> z) <span class="ot">=</span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">unlines</span> <span class="op">$</span> <span class="fu">map</span> dispLine <span class="op">$</span> toList z <span class="dv">6</span></span></code></pre></div>
<p>Here is the classic glider pattern to test. The definition has a lot of
boilerplate because we did not bother to create a <code>fromList</code> function.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">glider ::</span> <span class="dt">Z</span> <span class="dt">Bool</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>glider <span class="ot">=</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> <span class="op">$</span> <span class="dt">LZ</span> (<span class="fu">repeat</span> fz) fz rs</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>      rs <span class="ot">=</span> [ line [f, t, f]</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>           , line [f, f, t]</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>           , line [t, t, t]</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>           ] <span class="op">++</span> <span class="fu">repeat</span> fz</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>      t <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>      f <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>      fl <span class="ot">=</span> <span class="fu">repeat</span> f</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>      fz <span class="ot">=</span> <span class="dt">LZ</span> fl f fl</span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a>      line l <span class="ot">=</span></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">LZ</span> fl f (l <span class="op">++</span> fl)</span></code></pre></div>
<pre><code>*Main&gt; putStr $ disp glider
             
             
             
             
             
             
             
        *    
         *   
       ***   
             
             
             
*Main&gt; putStr $ disp $ evolve glider
             
             
             
             
             
             
             
             
       * *   
        **   
        *    
             
             </code></pre>
<p>We did it ! Implementing Conway’s Game of Life is usually full of ad-hoc
boilerplate code : iterating loops, managing copies of cells, etc. Using the
comonadic structure of cellular automata, the code can be a lot simpler.</p>
<p>In this example, <code>ListZipper</code> and <code>Z</code> should be library functions, so the actual
implementation is only a dozen lines long!</p>
<p>The real benefit is that it has really helped be grasp the concept of comonads.
I hope that I did not just fall into the comonad tutorial fallacy :)</p>
<p><strong>Update (March 10th):</strong> Brian Cohen contributed <a href="http://lpaste.net/83811">a simple extension to simulate
a closed topology</a>. Thanks !</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Or download the <a href="https://github.com/emillon/blog.emillon.org">source on github</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>In the real Haskell typeclass, there are the following differences: Monad
and Functor are not related, <code>join</code> is a library function (you can’t use
it to define an instance), <code>(&gt;&gt;=)</code> is used instead of its flipped
counterpart <code>(=&lt;&lt;)</code> and there two more methods <code>(&gt;&gt;)</code> and <code>fail</code>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>Simulating a closed topology such as a torus may even be possible using
cyclic lists instead of lazy infinite lists.
<strong>Update:</strong> see Brian Cohen’s response at the end of this post.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>At first I thought that it was possible to only use the <code>Comonad</code> instance
of <code>ListZipper</code> to define <code>horizontal</code> and <code>vertical</code>, but I couldn’t come
up with a solution. But in that case, the <code>z</code> generic parameter is
instanciated to <code>Z</code>, not <code>ListZipper</code>. For that reason I believe that my
initial thought can’t be implemented. Maybe it’s possible with a comonad
transformer or something like that.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p>This could have been written in extension as there are only 8 cases, but
it’s funnier and arguably less error prone this way :-)<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>]]></description>
    <pubDate>Thu, 18 Oct 2012 00:00:00 UT</pubDate>
    <guid>http://blog.emillon.org/posts/2012-10-18-comonadic-life.html</guid>
    <dc:creator>Etienne Millon</dc:creator>
</item>

    </channel>
</rss>
