<?xml version="1.0"?>
<!-- name="generator" content="blosxom/2.0" -->
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
  <channel>
    <title>blog 21   </title>
    <link>http://twan.home.fmf.nl/blog</link>
    <description>Twan van Laarhoven's weblog</description>
    <language>en</language>

  <item>
    <title>Four ways to fold an array</title>
    <link>http://twan.home.fmf.nl/blog/haskell/four-ways-to-fold.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/four-ways-to-fold.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As most Haskell programmers know, there are two ways to fold a list:
from the right with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt;
and from the left with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;/span&gt;&lt;/tt&gt;.
&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt; is corecursive (productive), which is great when the output can be produced lazily.
&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;/span&gt;&lt;/tt&gt; (or better, its strict cousin &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;/span&gt;'&lt;/tt&gt;) is tail recursive, preventing stack overflows.&lt;/p&gt;&lt;p&gt;We can define analogous operations for other data structures like 1-dimensional arrays.
Libraries like 'Data.ByteString' and 'Data.Vector' provide these.
But as I will show in this post there are more fold operations than the common two.&lt;/p&gt;&lt;p&gt;The data type I will use in this post is simply&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;-- and two utility functions for getting the lower and upper bounds&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;snd&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The right fold applies a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; to the current value and the folded result of the rest of the array:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;)
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;))&lt;/pre&gt;&lt;p&gt;The (strict) left fold uses an accumulator parameter:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;)
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;)) (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;In each case, the recursive &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt;&lt;/tt&gt; function is very similar in structure to the list version;
only instead of recursing for the tail of the list we recurse for index &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;/tt&gt;.
The time and space behavior is also similar.
For example, if you have a large array&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;6&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Then for computing something like the sum of all elements, you should use a strict left fold:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
50000005000000
&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
*** Exception: stack overflow&lt;/pre&gt;&lt;p&gt;On the other hand, a right fold is the way to go when you are only interested in a part of a lazily produced result. For example when converting an array to a list:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
[1,2,3,4,5,6,7,8,9,10]
(0.02 secs, 520824 bytes)
&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
[1000000,999999,999998,999997,999996,999995,999994,999993,999992,999991]
(5.89 secs, 263122464 bytes)&lt;/pre&gt;&lt;p&gt;All of this is exactly the same as with lists.&lt;/p&gt;&lt;p&gt;
&lt;br&gt;
But, if you look at &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, you will see that they both contain a loop doing &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)&lt;/tt&gt;.
So in a sense, both of these functions work from left to right!&lt;/p&gt;&lt;p&gt;Because arrays allow for random access, it is possible to make true right to left folds,
just start at the end and do &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)&lt;/tt&gt; in each iteration.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;foldl&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;)
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)) (&lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;foldr'&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array1D&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;foldr'&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;)
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Just look at the pretty duality there! We now have a &lt;em&gt;lazy&lt;/em&gt; left fold and a &lt;em&gt;strict&lt;/em&gt; right fold.&lt;/p&gt;&lt;p&gt;
The behavior is exactly the opposite of that of the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fold&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; functions above:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldl&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
*** Exception: stack overflow
&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr'&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
50000005000000&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr'&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
[1,2,3,4,5,6,7,8,9,10]
(6.19 secs, 263055372 bytes)
&lt;span class=&quot;input&quot;&gt;*Main&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;take&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldl&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;testArray&lt;/span&gt;
[1000000,999999,999998,999997,999996,999995,999994,999993,999992,999991]
(0.00 secs, 524836 bytes)&lt;/pre&gt;&lt;p&gt;To summarize, four ways to fold an array are:
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt;&lt;/tt&gt; to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;hi&lt;/span&gt;&lt;/tt&gt; to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;lo&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;corecursion, productive, lazy&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;tr&gt;
&lt;tr&gt;&lt;td&gt;accumulator, tail recursive, strict&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl'&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr'&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;tr&gt;
&lt;/table&gt;&lt;p&gt;Exercise: can you think of other ways to fold an array?&lt;/p&gt;</description>
  </item>
  <item>
    <title>CPS based functional references</title>
    <link>http://twan.home.fmf.nl/blog/haskell/cps-functional-references.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/cps-functional-references.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, download source code here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I have recently come up with a new way of representing functional references.&lt;/p&gt;&lt;p&gt;As you might recall, functional references (also called lenses) are like a pointer into a field of some data structure.
The value of this field can be extracted and modified.
For example:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;GHCi&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;123&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;hey&quot;&lt;/span&gt;)
&lt;span class=&quot;num&quot;&gt;123&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;GHCi&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;456&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;123&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;hey&quot;&lt;/span&gt;)
(&lt;span class=&quot;num&quot;&gt;456&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;hey&quot;&lt;/span&gt;)
&lt;span class=&quot;input&quot;&gt;GHCi&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) (&lt;span class=&quot;num&quot;&gt;123&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;hey&quot;&lt;/span&gt;)
(&lt;span class=&quot;num&quot;&gt;246&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;hey&quot;&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;where &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt;&lt;/tt&gt; is a functional reference to the first element of a pair.
It has the type &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;, i.e. in a 'record' of type &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/tt&gt; it points to an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;Previous representations relied on a record that contained the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt;&lt;/tt&gt; or the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt;&lt;/tt&gt; an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt;&lt;/tt&gt; functions.
But there is a much nicer looking representation possible using Functors.&lt;/p&gt;&lt;p&gt;
&lt;br&gt;First of all we will need a language extension and some modules:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;pragmac&quot;&gt;&lt;span class=&quot;pragma&quot;&gt;{-# LANGUAGE&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Rank2Types&lt;/span&gt; &lt;span class=&quot;pragma&quot;&gt;#-}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Control.Applicative&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Control.Monad.Identity&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now the representation for functional references I came up with is:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;forall&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;This type looks a lot like a continuation passing style function, which would be simply &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;)&lt;/tt&gt;, but where the result is &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; instead of any &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;&lt;/tt&gt;.
With different functors you get different behaviors. With the constant functor we can &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt;&lt;/tt&gt; the field pointed to:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getConst&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Const&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;While the identity functor allows a function us to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt;&lt;/tt&gt; the field:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;runIdentity&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Identity&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;)

&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;modify&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;As an example of an 'instance', here is the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt;&lt;/tt&gt; function I used in the introduction:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a_to_fa&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;',&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a_to_fa&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If we had &lt;a href=&quot;http://hackage.haskell.org/trac/ghc/ticket/3377&quot;&gt;tuple sections&lt;/a&gt; it could be written as simply
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;br&gt;To get access to inner fields, functional references can be composed. So &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fstF&lt;/span&gt;&lt;/tt&gt; points to the first element inner inside the first outer element of a nested pair.
One of the things that I like about the cps/functor based representation is that composition is quite beautiful and symmetric:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;idF&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;idF&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Let me conclude with the pair operator, called &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;***&lt;/span&gt;)&lt;/tt&gt; in Control.Arrow.
Unfortunately this operator is not as easy to define.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;pair&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefF&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;pair&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cd_to_fcd&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;some_ugly_code&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;In fact, the only way I know of implementing pair is by moving back and forth to a get/set representation&lt;/p&gt;&lt;pre&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;some_ugly_code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fcd&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cd_to_fcd&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)      &lt;span class=&quot;comment&quot;&gt;-- :: f (c,d)&lt;/span&gt;
             &lt;span class=&quot;varid&quot;&gt;cd_to_ab&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;-- :: (c,d) -&gt; (a,b)&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cd_to_ab&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fcd&lt;/span&gt;                        &lt;span class=&quot;comment&quot;&gt;-- :: f (a,b)&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The problem is that we need to split one function of type &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)&lt;/tt&gt; into two, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;&lt;/tt&gt;, because that is what the left and right arguments expect.
Then later, we would need to do the reverse and combine two of these functions again.&lt;/p&gt;&lt;p&gt;Does anyone have a better suggestion for implementing &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;pair&lt;/span&gt;&lt;/tt&gt;?&lt;/p&gt;</description>
  </item>
  <item>
    <title>Where do I get my non-regular types?</title>
    <link>http://twan.home.fmf.nl/blog/haskell/non-regular2.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/non-regular2.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, view the source code here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/non-regular1.lhs&quot;&gt;Friday I wrote&lt;/a&gt; about the type&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;))&lt;/pre&gt;&lt;p&gt;Where did this type come from? What can you use it for?&lt;/p&gt;&lt;p&gt;The story starts with another way of constructing &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt;&lt;/tt&gt;s, besides &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt;&lt;/tt&gt;.
For contrast I will call it 'impure'.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;I claim that &lt;em&gt;any&lt;/em&gt; FunList can be written in the form&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;for some &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, etc. In other words, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt;&lt;/tt&gt; are all that you need.
The following function converts a FunList to the above form, where &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt;&lt;/tt&gt; and the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt;&lt;/tt&gt; instance are left as parameters:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If you use this with the Applicative instance from last time you will find that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt;&lt;/tt&gt;!, I have written a reverse function without realizing it. Since this time we &lt;em&gt;don't&lt;/em&gt; want to reverse the list, I am going to turn the Applicative instance around for this post:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; ((&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;To support my claim above I need to prove that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/tt&gt;. This is a simple exercise in proof by induction. First of, we have that&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now assume that the theorem holds for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/tt&gt;, i.e. &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/tt&gt;. Then&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;  &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;)
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- by induction hypotheis&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;)
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; ((&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;)
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;))
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;)
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;By induction &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/tt&gt; for all &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;
&lt;br&gt;
I actually came upon FunList from the other direction.
I started with the higher order type&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;ApplicativeFunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;forall&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;An ApplicativeFunList is a function of the form &lt;tt&gt;&lt;span class=&quot;varop&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;applicativeStuff&lt;/span&gt;&lt;/tt&gt;. Since the applicativeStuff has to work for &lt;em&gt;any&lt;/em&gt; applicative functor it can only use operations from that class in addition to the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt;&lt;/tt&gt; argument. Because of the Applicative laws, things like &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;anything&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt; are the same as &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;anything&lt;/span&gt;&lt;/tt&gt;, so the only interesting functions of this form are&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varop&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;-- etc.&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Which is precisely what a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt;&lt;/tt&gt; can represent!
Indeed, we can convert any FunList to an ApplicativeFunList, and back again:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;toAFL&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;ApplicativeFunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;toAFL&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fl&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;imp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fl&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;fromAFL&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;ApplicativeFunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;fromAFL&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;afl&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;afl&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We already know that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromAFL&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;toAFL&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;withImpure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;impure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/tt&gt;. The other way around, I claim (but do not prove yet) that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;toAFL&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromAFL&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/tt&gt;. Hence, &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;ApplicativeFunList&lt;/span&gt;&lt;/tt&gt; are isomorphic!&lt;/p&gt;</description>
  </item>
  <item>
    <title>A non-regular data type challenge</title>
    <link>http://twan.home.fmf.nl/blog/haskell/non-regular1.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/non-regular1.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, download source code here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;While playing around with generalized functional references I encountered the following list-like data type:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;))&lt;/pre&gt;&lt;p&gt;This is a non-regular data type, meaning that inside the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; there is a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;i&gt;not-b&lt;/i&gt;&lt;/tt&gt;. So, what does a value of this type look like? Well, it can be
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/tt&gt;, or&lt;/li&gt;
&lt;li&gt; &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;))&lt;/tt&gt;, or&lt;/li&gt;
&lt;li&gt; &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)))&lt;/tt&gt;, etc.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
We either have just &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, or an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, or two &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;s (i.e. &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;&lt;span class=&quot;math&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;) and a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, or &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;&lt;span class=&quot;math&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/span&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, etc.&lt;/p&gt;&lt;p&gt;A &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; is therefore a list of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;s together with a function that takes &lt;em&gt;exactly&lt;/em&gt; that number of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;s to give you a &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;.
Extracting the single represented &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; value is easy:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;As is getting to the list of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;s:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; 
&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;)   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;But then things quickly get much trickier.
Since a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; holds exactly one &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, we might ask how much access we have to it.
First of, &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; is a Functor, so the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; value can be changed:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;The above case for &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt;&lt;/tt&gt; looks a bit strange, but remember that the data type is non-regular, so we recurse with a different function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt;. In this case instead of having type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;/tt&gt; as the outer &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; does, we need something with type &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt;&lt;/tt&gt; instance is even stranger. There is a &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;flip&lt;/span&gt;&lt;/tt&gt; there, where the heck did that come from?&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt;
    &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;   &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;                    &lt;span class=&quot;comment&quot;&gt;-- follows from Applicative laws&lt;/span&gt;
    &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;flip&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)   &lt;span class=&quot;comment&quot;&gt;-- flip??&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Aside from manipulating the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; value we can also do more list like things to the list of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;s, such as zipping:
&lt;/p&gt;  
&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;zipFun&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;zipFun&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)   &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;          &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;zipFun&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;          (&lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Done&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;getB&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;zipFun&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) (&lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;More&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;applyPair&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zipFun&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;applyPair&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Surprisingly, the applicative operator defined above can be used as a kind of append, just look at the type:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;(&amp;lt;*&gt;) :: FunList a (b -&gt; c) -&gt; FunList a b -&gt; FunList a c&lt;/pre&gt;&lt;p&gt;
it takes two 'lists' and combines them into one. It is indeed true that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;
This is as far as I got, so I will end this post with a couple of challenges:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Show that &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; is a monad.&lt;/li&gt;
&lt;li&gt; Show that &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; is not a monad.&lt;/li&gt;
&lt;li&gt; Write a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;reverseFun&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FunList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; that reverses a FunList, i.e. &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverseFun&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;getAs&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt; Write a &lt;span class=&quot;math&quot;&gt;O(n)&lt;/span&gt; reverse function.&lt;/li&gt;&lt;/ul&gt;</description>
  </item>
  <item>
    <title>Knight in n, part 4: tensors</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Knight4.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/Knight4.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Previously in this series:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight1.details&quot;&gt;part 1: moves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight2.details&quot;&gt;part 2: combinatorics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight3.details&quot;&gt;part 3: rings&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Welcome to the fourth installement of the &lt;em&gt;Knight in n&lt;/em&gt; series.
In part 3 we talked about the direct product of rings, and how they helped us solve the knight moves problem.
This time yet another type of product is going to help in decomposing the algorithm to allow faster parts to be put in.&lt;/p&gt;
&lt;h3&gt; The tensor product of rings &lt;/h3&gt;&lt;p&gt;In part three I introduced the direct product on rings, which is nothing more than a pair of numbers.
Confusingly this operation is also called &lt;a href=&quot;http://en.wikipedia.org/wiki/Direct_sum&quot;&gt;direct &lt;em&gt;sum&lt;/em&gt;&lt;/a&gt;.
To illustrate this name, take the direct sum/product of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; with &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;.
For every index &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; (within the bounds of the first array) there is a value of type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;, and for every index &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;/tt&gt; there is a value of type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;.
Instead of a pair of arrays, this could also be implemented as a single array
with the type &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) (&lt;span class=&quot;conid&quot;&gt;Either&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/tt&gt;. &quot;Either&quot; is just Haskell's way of saying &quot;disjoint union&quot; or &quot;sum type&quot;, hence &quot;direct &lt;em&gt;sum&lt;/em&gt;&quot;.&lt;/p&gt;&lt;p&gt;There is another product operation that we can perform on two rings: the &lt;a href=&quot;http://en.wikipedia.org/wiki/Tensor_product&quot;&gt;tensor product&lt;/a&gt;.
Dually to the direct sum, the tensor product of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; has type &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/tt&gt;.
The definition is very simple: the array contains all pairs where the first part comes from the first array, and the second part comes from the second array.&lt;/p&gt;&lt;p&gt;Slightly more generally, we can use any combining function. The general tensor product of two arrays can be implemented as:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;tensorWith&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Ix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Ix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;tensorWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;array&lt;/span&gt; ((&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;),(&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;))
      &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; ((&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;), &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
        (&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Usually elements are multiplied:&lt;/p&gt;&lt;pre&gt;(&lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Ix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Ix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
(&lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;tensorWith&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;The mathematical notation for this &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt;)&lt;/tt&gt; operator is &amp;otimes;.
Now an example:
Here we take two &lt;span class=&quot;math&quot;&gt;4&lt;/span&gt;-element vectors, their tensor product has &lt;span class=&quot;math&quot;&gt;4*4=16&lt;/span&gt; elements.
The two vectors are &quot;one dimensional&lt;a href=&quot;#footnote-dimension&quot; name=&quot;footnote-dimension-back&quot;&gt;*&lt;/a&gt;&quot; objects, their tensor product is a &quot;two dimensional&quot; matrix.
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/tensor-product1.png&quot; class=&quot;latex&quot; alt=&quot;
	\begin{pmatrix}
	 1\\2\\3\\4
	\end{pmatrix}
	 \otimes
	\begin{pmatrix}
	 a\\c\\d\\e
	\end{pmatrix}
	 = 
	\begin{pmatrix}
	 1a &amp; 1b &amp; 1c &amp; 1d \\
	 2a &amp; 2b &amp; 2c &amp; 2d \\
	 3a &amp; 3b &amp; 3c &amp; 3d \\
	 4a &amp; 4b &amp; 4c &amp; 4d \\
	\end{pmatrix}&quot;&gt;&lt;p&gt;
A special case we will use often is the tensor product of an array with itself:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;For example (using &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/simple-reflection-of-expressions.details&quot;&gt;simple reflection of expressions&lt;/a&gt; which is now on hackage as &lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/simple-reflect&quot;&gt;Debug.SimpleReflect&lt;/a&gt;):&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight4&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; ((&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;
                        ,&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;
                        ,&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt; Interchange law &lt;/h3&gt;&lt;p&gt;The tensor product and convolution operations satisfy the very useful &lt;em&gt;interchange law&lt;/em&gt;:
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/tensor-interchange.png&quot; class=&quot;latex&quot; alt=&quot;
	(a \otimes b) * (c \otimes d) = (a * c) \otimes (b * d)&quot;&gt;&lt;p style=&quot;margin-top:.1em&quot;&gt;
And since exponentiation is repeated convolution, also
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/tensor-interchange-exponent.png&quot; class=&quot;latex&quot; alt=&quot;
	(a \otimes b)^n = a^n \otimes b^n&quot;&gt;&lt;p&gt;For a proof sketch of this equation,
compare the definitions of &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt;)&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;mulArray&lt;/span&gt;&lt;/tt&gt;. Ignoring array bounds stuff, we have:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;convolution&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;     &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; ( &lt;strong&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;/strong&gt;,  &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;tensor&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;strong&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;)&lt;/strong&gt;, &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
The only difference is in what happens to indices, with convolution the indices are added, with the tensor product a pair is formed. Now consider the interchange law. Informally, the indices of the left hand side are of the form &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;c&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;d&lt;/sub&gt;&lt;/span&gt;)&lt;/tt&gt;, and on the right hand side &lt;tt&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;c&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;sub&gt;d&lt;/sub&gt;&lt;/span&gt;)&lt;/tt&gt;. This corresponds exactly to the piecewise addition for &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; (α,β)&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The interchange law is often exploited to perform faster convolutions.
For example, consider blurring an image by taking the convolution with a Gaussian blur kernel:
&lt;br&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/convolution-blur1.png&quot; alt=&quot;image*blur=blurred_image&quot; style=&quot;margin-left:2em;margin-top:2px;&quot;&gt;
&lt;br&gt;Performing this convolution requires &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;4&lt;/sup&gt;)&lt;/span&gt; operations for an &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; by &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; image.&lt;/p&gt;&lt;p&gt;The two dimensional Gaussian blur kernel can be written as the tensor product of two one dimensional kernels,
with a bit algebra this gives:
&lt;br&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/convolution-blur2.png&quot; alt=&quot;&quot; style=&quot;margin-left:0;margin-top:2px;&quot;&gt;&lt;/p&gt;&lt;p&gt;So now to blur an image we can perform two convolution, first with the horizontal kernel, and then with the vertical one:
&lt;br&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/convolution-blur3.png&quot; alt=&quot;image*blurH*blurV=blurred_image&quot; style=&quot;margin-left:2em;margin-top:2px;&quot;&gt;
&lt;br&gt;This procedure needs only &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;3&lt;/sup&gt;)&lt;/span&gt; operations.&lt;/p&gt;
&lt;h3&gt; Back to business &lt;/h3&gt;&lt;p&gt;Blurring images is not what we are trying to do.
Instead of convolution with the Gaussian blur kernel, we are interested in convolution with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt;&lt;/tt&gt;.
We could try the same trick, finding an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; such that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;.
Unfortunately, this is impossible.&lt;/p&gt;&lt;p&gt;But we can still get close, there &lt;em&gt;is&lt;/em&gt; a way to write &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, well, almost.
Actually, what we have is:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt;
      0 2 0 2 0        1 1 0 1 1      1 -1  0 -1  1 
      2 0 0 0 2        1 1 0 1 1     -1  1  0  1 -1 
 ==   0 0 0 0 0   ==   0 0 0 0 0  -   0  0  0  0  0   ==   square a - square b
      2 0 0 0 2        1 1 0 1 1     -1  1  0  1 -1 
      0 2 0 2 0        1 1 0 1 1      1 -1  0 -1  1 &lt;/pre&gt;&lt;p&gt;where&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Now we can start with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; from last time:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Where &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;safeAt&lt;/span&gt;&lt;/tt&gt; is a safe array indexing operator, that returns &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt; for indices that are out of bounds:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;safeAt&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;inRange&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;             &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now let's do some algebraic manipulation:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;    &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- by definition of paths&lt;sub&gt;conv&lt;/sub&gt; -}&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- by defintion of a and b -}&lt;/span&gt;
    ((&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- division by 2 is pseudocode&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- division does not depend on the index -}&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We still cannot apply the interchange law, because the exponentiation &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;)&lt;/tt&gt; is applied to the difference of two tensor products and not a single one.
We can, however, expand this exponentation by the formula:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;(&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This is just the usual &lt;a href=&quot;http://en.wikipedia.org/wiki/Binomial_theorem&quot;&gt;binomial expansion&lt;/a&gt;, as in
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/binomial-expansion-2.png&quot; class=&quot;latex&quot; alt=&quot;
	(x+y)^2 &amp;= x^2 + 2xy + y^2\\
	(x+y)^3 &amp;= x^3 + 3x^2y + 3xy^2 + y^3\\
	\text{etc.}&quot;&gt;&lt;p&gt;Applying binomial expansion to our work-in-progress gives:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;    (&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- binomial expansion -}&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
        &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- (-square b)^n&lt;sub&gt;b&lt;/sub&gt; == (-1)^n&lt;sub&gt;b&lt;/sub&gt; * square b^n&lt;sub&gt;b&lt;/sub&gt; -}&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
        &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
        &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- interchange law -}&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
        &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;)
        &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- move `safeAt` inwards, since addition is pointwise -}&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
        &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
        &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Fast indexing &lt;/h3&gt;&lt;p&gt;Since &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; &lt;em&gt;&lt;span class=&quot;varid&quot;&gt;something&lt;/span&gt;&lt;/em&gt;&lt;/tt&gt; already has &lt;span class=&quot;math&quot;&gt;n&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt; elements and the loop is performed &lt;span class=&quot;math&quot;&gt;n+1&lt;/span&gt; times,
this algorithm still requires &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;3&lt;/sup&gt;)&lt;/span&gt; operations.&lt;/p&gt;&lt;p&gt;The only reason for calculating &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;)&lt;/tt&gt; is because we need the element at index &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;&lt;/tt&gt;.
So instead of constructing a whole array, let's just calculate that single element:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- square x `safeAt` ij  ==  x `squareAt` ij&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`squareAt`&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So the inner part of the algorithm becomes:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;    &lt;span class=&quot;varid&quot;&gt;square&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- property of squareAt -}&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`squareAt`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We are still not there yet. Both &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; have &lt;span class=&quot;math&quot;&gt;O(n)&lt;/span&gt; elements, so just calculating their convolution takes &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt; work. But again, we need only two elements of the convolution, so we can define:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- a * b `safeAt` i  ==  mulArrayAt a b i&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mulArrayAt&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`safeAt`&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;And update &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;squareAt&lt;/span&gt;&lt;/tt&gt; accordingly:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mulSquareAt&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mulArrayAt&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mulArrayAt&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Finally we need a more efficient way to calculate all the powers of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;.
The &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;iterate&lt;/span&gt;&lt;/tt&gt; function can help us with that:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight4&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;iterate&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;, &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Putting the pieces together gives a &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt; algorithm for the knight moves problem:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;tensor&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;
            &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mulSquareAt&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;powers_of_a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;powers_of_b&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
            &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
            &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
       &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;powers_of_a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;iterate&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;varid&quot;&gt;powers_of_b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;iterate&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Note that the savings we have made do not come directly from decomposing the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt;&lt;/tt&gt;. It is just that this decomposition allows us to see that we are computing all elements of am expensive product where a single one would do.&lt;/p&gt;&lt;p&gt;This post brings another order of improvement.
Do you think you can do better than &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt; time and &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt; space complexity? If so I would like to hear.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;a name=&quot;footnote-dimension&quot; href=&quot;#footnote-dimension-back&quot;&gt;*&lt;/a&gt;: The number of elements is often called the dimension of a vector. Here we use the term dimension to refer to the number of indices used, also known as the &lt;a href=&quot;http://en.wikipedia.org/wiki/Tensor_order#Tensor_rank&quot;&gt;(tensor) order&lt;/a&gt;. So a &lt;span class=&quot;math&quot;&gt;100*100&lt;/span&gt; pixel image has dimension &lt;span class=&quot;math&quot;&gt;10000&lt;/span&gt; according to the first interpretation (the number of elements), but dimension two in the second interpretation (the number of indices).&lt;/p&gt;</description>
  </item>
  <item>
    <title>Knight in n, part 3: rings</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Knight3.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/Knight3.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Previously in this series:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight1.details&quot;&gt;part 1: moves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight2.details&quot;&gt;part 2: combinatorics&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In this third installment, we will look at how to use various types as numbers, i.e. how to make them an instance of the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt; type class.
The solution the Knight-moves-problem will emerge at the end, almost as if by magic. &lt;span class=&quot;math&quot;&gt;:)&lt;/span&gt;&lt;/p&gt;&lt;h3&gt; Tangent: Things as numbers &lt;/h3&gt;&lt;p&gt;Many types can be used as if they are numbers. Haskell-wise this means they can be an instance of the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt; type class. Mathematically it means that these types are &lt;a href=&quot;http://en.wikipedia.org/wiki/Ring_(algebra)&quot;&gt;rings&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt; Pairs as numbers &lt;/h4&gt;&lt;p&gt;Let's start with a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt; instance for pairs &lt;tt&gt;(α,β)&lt;/tt&gt;.
In general, our only choice is to do everything pointwise.
So for all operations &amp;otimes; (i.e. &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;)&lt;/tt&gt;, &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;)&lt;/tt&gt; and &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;)&lt;/tt&gt;:
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/pointwise_tuple.png&quot; class=&quot;latex&quot; alt=&quot;
	\begin{pmatrix}a\\b\end{pmatrix}
	 \otimes
	\begin{pmatrix}c\\d\end{pmatrix}
	 =
	\begin{pmatrix}a\otimes c\\b \otimes d\end{pmatrix}&quot;&gt;&lt;p&gt;In ring theory this is called the &lt;a href=&quot;http://en.wikipedia.org/wiki/Direct_product_(ring_theory)&quot;&gt;&lt;em&gt;direct product&lt;/em&gt;&lt;/a&gt;. In Haskell we can write it as:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; α, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; β) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; (α,β) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;     (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;    &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;    &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt;  (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;We could also make instances for triples, quadruples and other tuples this way, but those are not needed for the rest of the story.&lt;/p&gt;&lt;h4&gt; Arrays as numbers &lt;/h4&gt;&lt;p&gt;A more general kind of tuple is an array; which is somewhat like a tuple of arbitrary size.
Of course, that is not quite true, since two arrays with the same type can have a &lt;em&gt;different&lt;/em&gt; size.
One way around this problem is to treat all arrays as if they are infinite, by taking values outside the bounds to be equal to &lt;span class=&quot;math&quot;&gt;0&lt;/span&gt;. So
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&amp;infin;,&amp;infin;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- pseudocode&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;That way we can still do addition pointwise,
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/pointwise_add_array.png&quot; class=&quot;latex&quot; alt=&quot;
	\begin{pmatrix}a\\b\\\vdots\end{pmatrix}
	 +
	\begin{pmatrix}c\\d\\\vdots\end{pmatrix}
	 =
	\begin{pmatrix}a+c\\b+d\\\vdots\end{pmatrix}&quot;&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;accumArray&lt;/span&gt;&lt;/tt&gt; function can help with the missing elements by setting them to &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt; by default:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;addArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;accumArray&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;a&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
        (&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;lo&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;sub&gt;hi&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Next up is the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt;&lt;/tt&gt; function.
&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt; is easy; there are two options for other values&lt;/p&gt;&lt;ol&gt;&lt;li&gt; &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; is an infinite array of values &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt; &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; is an array with values &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; at some single point.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The first choice mimics the definition for tuples, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;)&lt;/tt&gt;.
But for arrays this has the slight problem of requiring an infinite array.
For the second alternative we need to pick the index where to put the number &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt;. The obvious choice is to put &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; at 'the origin', index &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;intArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Finally, multiplication. As you have learned in school, multiplication can be seen as repeated addition, In our Haskell world that means that we expect the law &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; to hold.&lt;/p&gt;&lt;p&gt;If we had used the first choice for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt;&lt;/tt&gt; then multiplication could be done pointwise as it was for tuples. But we have made a different choice, so now &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;/tt&gt; is an array that contains the value &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;/tt&gt; at index &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt; (and is implicitly zero everywhere else). When calculating &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;, this &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;/tt&gt; should by multiplied with &lt;em&gt;all&lt;/em&gt; elements of the array &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The operation that does the right thing is &lt;a href=&quot;http://en.wikipedia.org/wiki/Convolution&quot;&gt;&lt;em&gt;convolution&lt;/em&gt;&lt;/a&gt;. It looks like this:
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/pointwise_mul_array.png&quot; class=&quot;latex&quot; alt=&quot;
	\begin{pmatrix}a\\b\\c\end{pmatrix}
	 *
	\begin{pmatrix}d\\e\\f\end{pmatrix}
	 \; = \;
	\raisebox{5mm }{$a\begin{pmatrix}d\\e\\f\end{pmatrix}$} +
	\raisebox{0mm }{$b\begin{pmatrix}d\\e\\f\end{pmatrix}$} +
	\raisebox{-5mm}{$c\begin{pmatrix}d\\e\\f\end{pmatrix}$}
	 \; = \;
	\left(\begin{array}{@{}c@{}c@{}c@{}c@{}c@{}}
	     ad&amp;&amp;&amp;&amp;\\ae&amp;+&amp;bd&amp;&amp;\\af&amp;+&amp;be&amp;+&amp;cd\\&amp;&amp;bf&amp;+&amp;ce\\&amp;&amp;&amp;&amp;cf
	\end{array}\right)&quot;&gt;&lt;p&gt;So for each element &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;/tt&gt; at index &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt; in the first array, we shift a copy of the second array so that its origin becomes &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt;. This copy is multiplied by &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;/tt&gt; and all these copies are added.
If one of the arrays is &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;/tt&gt; (i.e. a scalar), then this corresponds to multiplying all elements in the other array by &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;&lt;/tt&gt;; exactly what we wanted.&lt;/p&gt;&lt;p&gt;Convolution can be implemented with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;accumArray&lt;/span&gt;&lt;/tt&gt; as:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mulArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;accumArray&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
      &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;assocs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Notice that we use the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; (α,β)&lt;/tt&gt; instance for the bounds, and that this definition is a nicely symmetrical.&lt;/p&gt;&lt;p&gt;
Putting it all together, we get the following instance:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Ix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;intArray&lt;/span&gt;
    (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;)         &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;addArray&lt;/span&gt;
    (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;)         &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mulArray&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;negate&lt;/span&gt;      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;negate&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;         &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt;      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;In mathematical terms, what we constructed here is called a &lt;a href=&quot;http://en.wikipedia.org/wiki/Group_ring&quot;&gt;&lt;em&gt;group ring&lt;/em&gt;&lt;/a&gt;. There is a group ring &lt;span class=&quot;math&quot;&gt;G[R]&lt;/span&gt; for any group &lt;span class=&quot;math&quot;&gt;G&lt;/span&gt; and ring &lt;span class=&quot;math&quot;&gt;R&lt;/span&gt;, which corresponds to an instance  &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;)&lt;/tt&gt; when &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt;&lt;/tt&gt; is a group (i.e. an instance of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt;) and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;&lt;/tt&gt; is a ring (also an instance of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;&lt;h4&gt; Arrays as polynomials &lt;/h4&gt;&lt;p&gt;Another way to interpret the above instance, is by treating arrays as polynomials over some variable &lt;span class=&quot;math&quot;&gt;x&lt;/span&gt;. The array &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;),(&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;),(&lt;span class=&quot;varid&quot;&gt;k&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;),&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt; then represents the polynomial &lt;span class=&quot;math&quot;&gt;ax&lt;sup&gt;i&lt;/sup&gt;+bx&lt;sup&gt;j&lt;/sup&gt;+cx&lt;sup&gt;k&lt;/sup&gt;+...&lt;/span&gt;. The addition and multiplication defined above now have the expected meaning, for example:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;comment&quot;&gt;--  2 + 3x + 4x&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;comment&quot;&gt;--  5x + 6x&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;array&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;8&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;10&lt;/span&gt;)&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;comment&quot;&gt;--  2 + 8x + 10x&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;array&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;10&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;27&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;38&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;24&lt;/span&gt;)&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;comment&quot;&gt;--  10x + 27x&lt;sup&gt;2&lt;/sup&gt; + 38x&lt;sup&gt;3&lt;/sup&gt; + 24x&lt;sup&gt;4&lt;/sup&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We can make this even more suggestive by defining:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;conid&quot;&gt;True&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If you are interested in this interpretation,
sigfpe wrote &lt;a href=&quot;http://sigfpe.blogspot.com/2007/11/small-combinatorial-library.html&quot;&gt;an interesting blog post&lt;/a&gt; about convolutions, polynomials and power series.&lt;/p&gt;&lt;h3&gt; It's magic! &lt;/h3&gt;&lt;p&gt;Now, let's go back to our original problem, the moves of a chess knight.&lt;/p&gt;&lt;p&gt;The positions reachable in a single move can be put into a two dimensional array (i.e. a matrix).&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Array&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;,&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;) &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;accumArray&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; ((&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This is the familiar &lt;em&gt;move matrix&lt;/em&gt;, which we already saw in part 1.
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight3&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;printMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt;
    0 1 0 1 0
    1 0 0 0 1
    0 0 0 0 0
    1 0 0 0 1
    0 1 0 1 0&lt;/pre&gt;&lt;p&gt;Now the magic.
We defined multiplication of two arrays &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; as adding copies of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; for each value in &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;.
If we use the move matrix as &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, then this means we add all possible destinations of a knight making one move from each place it can reach. Repeating this &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; times gives us our answer. Since repeated multiplication is exponentiation:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;allPaths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moveMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;For example, for &lt;span class=&quot;math&quot;&gt;n=2&lt;/span&gt;:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/convolution2.png&quot; alt=&quot;moveMatrix * moveMatrix&quot; style=&quot;margin-left:2em;&quot;&gt;&lt;/p&gt;&lt;p&gt;If we are interested in just a single point there is the array indexing operator (!!) to help us,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;inRange&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;             &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;allPaths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This convolutional algorithm can count the number of paths in &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;3&lt;/sup&gt;)&lt;/span&gt;, but not just for a single end point, but for &lt;em&gt;all&lt;/em&gt; end points at once! The program is also a lot simpler than the &lt;/p&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;conv&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; algorithm is pretty good, but we can &lt;em&gt;still&lt;/em&gt; do better.
Next time I will show how the algorithm from part 3 can be improved further, and curiously, how it will start to look more like the algorithm from part 2.&lt;/p&gt;</description>
  </item>
  <item>
    <title>Knight in n, part 2: combinatorics</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Knight2.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/Knight2.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Previously in this series:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/Knight1.details&quot;&gt;part 1: moves&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In my previous post I introduced the 'knight moves problem': How many ways are there for a chess knight to reach cell &lt;span class=&quot;math&quot;&gt;(i,j)&lt;/span&gt; in exactly &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; moves?
The recursive solution from last time is horribly inefficient for larger values of &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt;. Today I will show some more efficient solutions.&lt;/p&gt;&lt;h3&gt; Ignoring the order of moves &lt;/h3&gt;&lt;p&gt;If the knight first makes a move &lt;span class=&quot;math&quot;&gt;(-1,2)&lt;/span&gt; and then a move &lt;span class=&quot;math&quot;&gt;(2,1)&lt;/span&gt; it will end up at &lt;span class=&quot;math&quot;&gt;(1,3)&lt;/span&gt;.
If it first moves &lt;span class=&quot;math&quot;&gt;(2,1)&lt;/span&gt; and then &lt;span class=&quot;math&quot;&gt;(-1,2)&lt;/span&gt; it will also end up at &lt;span class=&quot;math&quot;&gt;(1,3)&lt;/span&gt;.
So, the order in which the moves happen does not matter for the final position!
We can exploit this fact to make a faster program.
Instead of determining what move to make at each step, we can count how many moves we make of each type and then determine in how many different orders these moves can be performed.&lt;/p&gt;&lt;p&gt;Denote by &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; the number of moves of the first type, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;123&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; the number of moves of type 1, 2 or 3, etc.
So &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, and since there are eight different moves, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/tt&gt;.
A count &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;ab&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; can be &lt;em&gt;split&lt;/em&gt; into &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;a&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; in several ways, for now we will consider all possibilities:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So for example, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;)&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;By repeatedly splitting &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/tt&gt; we arrive at:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;split&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2345678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;345678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;45678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;45678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Here we only keep sequences of moves that end up in &lt;span class=&quot;math&quot;&gt;(i,j)&lt;/span&gt;, as determined by the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;destination&lt;/span&gt;&lt;/tt&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;hs&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;hs&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unzip&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,(δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;)) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Next, we need to know how many different paths can be formed with a particular set of moves.
You might remember &lt;a href=&quot;http://en.wikipedia.org/wiki/Binomial_coefficient&quot;&gt;binomial coefficients&lt;/a&gt; from high school, which give the number of ways to pick &lt;span class=&quot;math&quot;&gt;k&lt;/span&gt; items from a set of size &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt;:
&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/multinomial-2-1-1.png&quot; alt=&quot;multinomial [2,1,1]&quot; style=&quot;float:right;margin-left:1em;border:1px solid #aaa;&quot;&gt;
&lt;/p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/binomial.png&quot; class=&quot;latex&quot; alt=&quot;
	\binom{n}{k} = \frac{n!}{k!(n-k)!}&quot;&gt;&lt;p&gt;If we take &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; equal to &lt;span class=&quot;math&quot;&gt;m+k&lt;/span&gt; we get the number of different lists containing exactly &lt;span class=&quot;math&quot;&gt;k&lt;/span&gt; red balls and &lt;span class=&quot;math&quot;&gt;m&lt;/span&gt; green balls. Or put differently, the number of different paths containing &lt;span class=&quot;math&quot;&gt;k&lt;/span&gt; moves of the first type and &lt;span class=&quot;math&quot;&gt;m&lt;/span&gt; moves of the second type. This interpretation of binomial coefficients can be generalized two more than two types, giving &lt;em&gt;multinomial coefficients&lt;/em&gt;. These are exactly what we need to determine the number of paths given the counts of each type of move:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;factorial&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;)
               &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;product&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;This multinomial function requires calculating a lot of factorials, to make this as fast as possible they should be stored in an &lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/UnboundedArray.details&quot;&gt;'array'&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unboundedArray&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;scanl&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Calculating &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;split&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; only takes &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;7&lt;/sup&gt;)&lt;/span&gt; integer operations, since each &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt;&lt;/tt&gt; effectively costs a factor &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/tt&gt;.
While this is better than the previous result, it is still not satisfactory.&lt;/p&gt;
&lt;h3&gt; Solving the guard condition &lt;/h3&gt;&lt;p&gt;The above function uses a &quot;generate and test&quot; approach: Generate all possibilities and test which ones reach the destination. It would be more efficient to generate &lt;em&gt;only&lt;/em&gt; those possibilities.&lt;/p&gt;&lt;p&gt;Algebraic reasoning can help us here. Let's start by expanding the condition in the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;guard&lt;/span&gt;&lt;/tt&gt; statement:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;   (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- by definition of destination -}&lt;/span&gt;
   (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;hs&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt;)
     &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;hs&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unzip&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,(δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;)) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- expand unzip and simplify -}&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;snd&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt;)
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- by definition of moves (see previous post) -}&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;counts&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- expanding the sum and product, remember n&lt;sub&gt;12&lt;/sub&gt; = n_1+2, etc. -}&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt;
&lt;span class=&quot;varop&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;{- reordering -}&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
   &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;These are equations we can work with.
Take the equation involving &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;/tt&gt;. We know that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, and that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;. From these two equations, we can solve for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, without needing an expensive &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- | find a and b such that a+b == c, a-b == d, a,b &gt;= 0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;
   &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)
   &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;                   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mzero&lt;/span&gt;
 &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;ok&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`divMod`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This gives an &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;5&lt;/sup&gt;)&lt;/span&gt; algorithm:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Multinomial laws &lt;/h3&gt;&lt;p&gt;It turns out that we don't actually need to know &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, etc.
If you think about it, the multinomial coefficient &lt;tt&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt; means: &quot;The number of different lists with &lt;span class=&quot;math&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; red balls, &lt;span class=&quot;math&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; of green balls, etc.&quot;. To make such a list we can first pick where to put the red balls, then where to put the blue balls, then the green balls and so on.&lt;/p&gt;&lt;p&gt;But we could also first decide where the brightly colored balls (red and green) go and where the dark collored ones (blue) go. Now there are only two types of balls, so this is a binomial coefficient, or in terms of a multinomial, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;rg&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;b&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt;. Then for the positions with brightly colored balls, we need to determine which ones are which color, which can be done in &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;r&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;g&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt; ways.  In a picture:&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/multinomial-law1.png&quot; alt=&quot;multinomial [2,1,1] = multinomial [3,1] * multinomial [2,1]&quot; style=&quot;margin-left:2em;border:1px solid #aaa;&quot;&gt;&lt;/p&gt;&lt;p&gt;This same arguments also holds when there are eight types of balls (or moves), so&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If you plug this into the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; function, you might notice that the last part of the function is calculating the product of two independent things. One part is about &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and the other about &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;.
Now remember that the function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt;&lt;/tt&gt; takes the sum of all possibilities, and that products distributes over sums. This means that the two loops for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; can be performed independently, giving us an &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;4&lt;/sup&gt;)&lt;/span&gt; algorithm:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O4&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;result&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
         (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;3&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;4&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;result&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
         (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;
         &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;8&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;result&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;result&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Here both of the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;result&lt;/span&gt;&lt;/tt&gt; parts are of the form&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;which just so happens to be equivalent to just &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt; (a proof of this statement is left as an exercise, i.e. I am too lazy to write it out).
This equation immediately leads to a (much simpler) &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;3&lt;/sup&gt;)&lt;/span&gt; algorithm:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O3&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12345678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt;
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;5678&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;)
    (&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;sub&gt;pm&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;1234&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;12&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;34&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;56&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;78&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
           &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;57&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;68&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
           &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;multinomial&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;13&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;sub&gt;24&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Verifying the results &lt;/h3&gt;&lt;p&gt;After all this manipulation it is a good idea to check whether the program still does the right thing.
We can either manually compare the path matrices:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;check&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Or use QuickCheck or SmallCheck:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight2&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;smallCheck&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;5&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;(&lt;span class=&quot;conid&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O3&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ij&lt;/span&gt;)
...
Depth 5:
  Completed 726 test(s) without failure.&lt;/pre&gt;&lt;p&gt;
Finally, to contrast with the first part of this series, here is the time it takes to calculate the number of paths in &lt;span class=&quot;math&quot;&gt;100&lt;/span&gt; steps:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight2&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O3&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;100&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;)
2422219241769802380469882122062019059350760968380804461263234408581143863208781993964800
(4.75 secs, 270708940 bytes)&lt;/pre&gt;&lt;p&gt;The recursive algorithm would need in the order of &lt;span class=&quot;math&quot;&gt;10&lt;sup&gt;77&lt;/sup&gt;&lt;/span&gt; years to arrive at this answer.&lt;/p&gt;&lt;p&gt;Still, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O3&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; is not the fastest possible algorithm.
Next time I will look at a completely different approach, but further improvements to the solution in this post are possible as well.
As an exercise for the reader, you should try transforming &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;O3&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; into an &lt;span class=&quot;math&quot;&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/span&gt; solution. Hint: there are more sums-of-products of independent values.
&lt;/p&gt;</description>
  </item>
  <item>
    <title>Knight in n, part 1: moves</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Knight1.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/Knight1.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Consider the following problem:&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;&lt;i&gt;
A knight is placed at the origin of a chessboard that is infinite in all directions.
How many ways are there for that knight to reach cell &lt;span class=&quot;math&quot;&gt;(i,j)&lt;/span&gt; in exactly &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; moves?
&lt;/i&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;This &lt;em&gt;knight moves problem&lt;/em&gt; is not hard, nor does it have any real life applications. The problem is still interesting because there are many different ways to solve it, ranging from very simple to quite complex. 
In this series of articles I will describe some of these solutions.&lt;/p&gt;&lt;h3&gt; Knight's moves &lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/chessboard1.png&quot; style=&quot;float:right;margin-left:1em;&quot; alt=&quot;The possible moves for a chess knight&quot;&gt;&lt;/p&gt;&lt;p&gt;In chess, a knight can move two squares horizontally and one square vertically, or two squares vertically and one square horizontally. One complete move therefore looks like the letter 'L'.
The picture on the right shows all possible moves for the black knight in the center.&lt;/p&gt;
&lt;p&gt;We can summarize all these moves in an array:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;,&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;)&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;)
        ,(&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;),(&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;)&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Counting the number of paths to &lt;span class=&quot;math&quot;&gt;(i,j)&lt;/span&gt; in &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt; steps can now be done with a simple recursive function.
The base case is that in &lt;span class=&quot;math&quot;&gt;0&lt;/span&gt; moves only cell &lt;span class=&quot;math&quot;&gt;(0,0)&lt;/span&gt; is reachable. In the recursion step we simply try all moves:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;,&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So for example
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight1&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths_rec&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)
54&lt;/pre&gt;&lt;p&gt;
I.e. there are 54 ways to reach cell &lt;span class=&quot;math&quot;&gt;(2,2)&lt;/span&gt; in &lt;span class=&quot;math&quot;&gt;4&lt;/span&gt; moves.&lt;/p&gt;&lt;p&gt;
Unfortunately the function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; is not very efficient. In fact, it is very much not efficient.
At each step all &lt;span class=&quot;math&quot;&gt;8&lt;/span&gt; possible moves are considered, so the total time complexity of this function is &lt;span class=&quot;math&quot;&gt;O(8&lt;sup&gt;n&lt;/sup&gt;)&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt; Tables &lt;/h3&gt;&lt;p&gt;Besides calculating the number of paths to a single point it can also be interesting to display the number of pats for each possible end point. We can make a list of lists containing all the path counts,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;pathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;and then display this list in a tabular format&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;showMatrix&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; α &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;α&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;showMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xss&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unlines&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unwords&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xss&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;printPathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showMatrix&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The path matrix for &lt;span class=&quot;math&quot;&gt;n=1&lt;/span&gt; should be familiar, it is the same as the image of possible moves of a knight.&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight1&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;printPathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
    0 1 0 1 0
    1 0 0 0 1
    0 0 0 0 0
    1 0 0 0 1
    0 1 0 1 0&lt;/pre&gt;&lt;p&gt;But now we can also make larger tables:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight1&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;printPathMatrix&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;
    0 0 1 0 2 0 1 0 0
    0 2 0 2 0 2 0 2 0
    1 0 0 0 2 0 0 0 1
    0 2 0 2 0 2 0 2 0
    2 0 2 0 8 0 2 0 2
    0 2 0 2 0 2 0 2 0
    1 0 0 0 2 0 0 0 1
    0 2 0 2 0 2 0 2 0
    0 0 1 0 2 0 1 0 0&lt;/pre&gt;&lt;p&gt;If you were to continue increasing &lt;span class=&quot;math&quot;&gt;n&lt;/span&gt;, the table and the numbers in it become ever larger.
It is a good idea to make a 'density plot', i.e. to use colors to visualize larger numbers. For example for &lt;span class=&quot;math&quot;&gt;n=4&lt;/span&gt;, the path matrix can be rendered as:
&lt;br&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/knight/knight-density4.png&quot; alt=&quot;&quot; style=&quot;vertical-align:middle;margin-left:2em;margin-top:3px;&quot;&gt;&lt;/p&gt;&lt;h3&gt; Special cases &lt;/h3&gt;&lt;p&gt;Looking at the above matrices, you might start to see some patterns emerge:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; A knight cannot move more than &lt;span class=&quot;math&quot;&gt;2n&lt;/span&gt; cells in any direction (horizontal or vertical).&lt;/li&gt;
&lt;li&gt; Similarly, the knight moves no more than &lt;span class=&quot;math&quot;&gt;3n&lt;/span&gt; squares in total.&lt;/li&gt;
&lt;li&gt; A knight always moves from a white square to a black square and vice-versa. In other words, the parity of &lt;span class=&quot;math&quot;&gt;i+j+n&lt;/span&gt; must be zero.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These observations can be used as additional cases in the recursive function to quickly eliminate large parts of the input space:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;,&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;`mod`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; /&lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;          &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;          &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; (δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;i&lt;/sub&gt;&lt;/span&gt;,δ&lt;span class=&quot;varid&quot;&gt;&lt;sub&gt;j&lt;/sub&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;moves&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;A quick test shows that this can be a big improvement for the run time:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Knight1&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;rec&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;8&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;)
124166
(92.88 secs, 4605991724 bytes)
&lt;span class=&quot;input&quot;&gt;Knight1&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;8&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;)
124166
(17.69 secs, 807191624 bytes)&lt;/pre&gt;&lt;p&gt;The asymptotic time complexity of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;paths&lt;sub&gt;case&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; is harder to analyze.
It is still &lt;span class=&quot;math&quot;&gt;O(8&lt;sup&gt;n&lt;/sup&gt;)&lt;/span&gt; in the worst case, but the complexity is now also output dependant.&lt;/p&gt;&lt;p&gt;
&lt;br&gt;That is all for now, next time we will look at smarter algorithms.
For the interested reader I would suggest that you try to come up with some ideas of your own. I would love to hear how other people approach this problem.
&lt;/p&gt;</description>
  </item>
  <item>
    <title>Arrays without bounds</title>
    <link>http://twan.home.fmf.nl/blog/haskell/UnboundedArray.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/UnboundedArray.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Regular old arrays have a size; you can't just have an infinite array.
On the other hand, a lazy language such as Haskell does allow infinite lists.
The idea behind the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;UnboundedArray&lt;/span&gt;&lt;/tt&gt; module is to combine the &lt;span class=&quot;math&quot;&gt;O(1)&lt;/span&gt; access of arrays with the unbounded size of lazy lists.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;UnboundedArray&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This data type is built on top of ordinary arrays and unsafe IO operations:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.Array&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.IORef&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;System.IO.Unsafe&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;To keep things simple, an unbounded array is just a function from the natural numbers to array elements:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;UnboundedArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
I am just going to dump the code here instead of explaining it.
The idea is to make an array and resize it when it becomes too small.
If the size increases geometrically with each resize, then the amortized cost of a single access will be &lt;span class=&quot;math&quot;&gt;O(1)&lt;/span&gt;.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- | Create an unbounded array from an infinite list&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;--   Accessing element /n/ takes /O(n)/ time, but only /O(1)/ amortized time.&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unboundedArray&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;UnboundedArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unboundedArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unsafePerformIO&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unsafePerformIO&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;unboundedArrayIO&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;)

&lt;span class=&quot;varid&quot;&gt;unboundedArrayIO&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;IO&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;unboundedArrayIO&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;theArray&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;newIORef&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;readIORef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theArray&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;size&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bounds&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;size&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;
          &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;size&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`div`&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)
                  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;listArray&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;size&lt;/span&gt;') &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;
                  &lt;span class=&quot;varid&quot;&gt;writeIORef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theArray&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;'
                  &lt;span class=&quot;varid&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ar&lt;/span&gt;' &lt;span class=&quot;varop&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So, what are UnboundedArrays good for?
A simple application is memoization, for example:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;memo&lt;sub&gt;Int&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unboundedArray&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;)

&lt;span class=&quot;varid&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;memo&lt;sub&gt;Int&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;realFib&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;realFib&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;varid&quot;&gt;realFib&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;varid&quot;&gt;realFib&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fib&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fib&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;)&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
[1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946]&lt;/pre&gt;&lt;p&gt;But since we can use an arbitrary list for initialization the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;unboundedArray&lt;/span&gt;&lt;/tt&gt; function can sometimes be more flexible/convenient than &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;memo&lt;sub&gt;Int&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;</description>
  </item>
  <item>
    <title>A generic merge function</title>
    <link>http://twan.home.fmf.nl/blog/haskell/generic-merge.details</link>
    <description>&lt;p&gt;
&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/generic-merge.lhs&quot; style=&quot;color:grey;font-size:smaller;&quot;&gt;[This post is literate Haskell, get the source here]&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When working with sorted lists you often come to the point where you want to combine two or more of them.
This &lt;em&gt;merge&lt;/em&gt; procedure forms the heart of &lt;a href=&quot;http://en.wikipedia.org/wiki/Merge_sort&quot;&gt;merge sort&lt;/a&gt;
it works something like:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
This &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt;&lt;/tt&gt; function is not in the Haskell standard library, and even if there were, it might not be very useful.&lt;/p&gt;&lt;p&gt;The problem is that when you need &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt;&lt;/tt&gt; you often need a slight variation.
For example, you might want to remove duplicates,
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;merge_union&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Or find the elements common to both lists,
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;merge_intersection&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Or you want the difference, the symmetric difference, or...&lt;/p&gt;&lt;p&gt;
&lt;br&gt;The solution for all these problems is to make a more general &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt;&lt;/tt&gt; function.
To do that we take a note from the most generic function over a single list, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt;.
The generic merge function is also a right fold, but over two lists.
Behold the type signature:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ordering&lt;/span&gt;)  &lt;span class=&quot;comment&quot;&gt;-- ^ cmp: Comparison function&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)    &lt;span class=&quot;comment&quot;&gt;-- ^ f&lt;sub&gt;xy&lt;/sub&gt;: Combine when a and b are equal&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)         &lt;span class=&quot;comment&quot;&gt;-- ^ f&lt;sub&gt;x&lt;/sub&gt;:  Combine when a is less&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)         &lt;span class=&quot;comment&quot;&gt;-- ^ f&lt;sub&gt;y&lt;/sub&gt;:  Combine when b is less&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;                     &lt;span class=&quot;comment&quot;&gt;-- ^ z:   Base case&lt;/span&gt;
         &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;       &lt;span class=&quot;comment&quot;&gt;-- ^ Argument lists and result list&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Don't be scared by the size. The reason there are a lot of arguments is that for each case we use a different combining function:
If the smallest element comes from the first list we use &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, if it comes from the second list we use &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;, and when the two elements are equal, we combine them both with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt;.
As in &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt; these calls to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;/&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt;/&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; are then chained like &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;sub&gt;1&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; (&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;))&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The lists from the example above can be aligned as follows:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;               &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,      &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,   &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,   &lt;span class=&quot;num&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;               &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;    &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,  &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,   &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;      &lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;use&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The function implementation is straightforward:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;     &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;of&lt;/span&gt;
              &lt;span class=&quot;conid&quot;&gt;LT&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;   (&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt;)
              &lt;span class=&quot;conid&quot;&gt;EQ&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;xy&lt;/sub&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;)
              &lt;span class=&quot;conid&quot;&gt;GT&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt;    &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;&lt;br&gt;Now, let's look at some uses of this function.
First of all, the usual merge sort &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt;&lt;/tt&gt; function:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mergeBy&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mergeBy&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;compare&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Instead of adding both &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; to the resulting list when they are equal, we can instead add only one of them, or even the result of some function on them.
This gives the set &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;union&lt;/span&gt;&lt;/tt&gt; operation:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;unionByWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unionWith&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unionByWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;compare&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;If we ignore elements that occur in only one of the lists by setting &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;x&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;sub&gt;y&lt;/sub&gt;&lt;/span&gt;&lt;/tt&gt; to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/tt&gt;, we get the intersection instead:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;intersectionByWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cmp&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;intersectionWith&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;intersectionByWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;compare&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
&lt;br&gt;With these merge functions, implementing merge sort becomes simple.
All that is left to do is split a list in two, and recursively sort and merge.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;zs&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zs&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;       &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;)

&lt;span class=&quot;varid&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;zs&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ys&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zs&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;If we replace &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;merge&lt;/span&gt;&lt;/tt&gt; by &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;unionWith&lt;/span&gt;&lt;/tt&gt; we instead get a sort that combines duplicate elements.&lt;/p&gt;&lt;p&gt;&lt;br&gt;Besides set operations, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt;&lt;/tt&gt; can also be (ab)used for other things, such as&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;intersectionByWith&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;EQ&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Or a variant of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt;&lt;/tt&gt;, that keeps the tail of the longer list:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unionByWith&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;EQ&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;We can even implement concatenation:&lt;/p&gt;&lt;pre&gt;(&lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mergeByR&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;LT&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(:)&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;</description>
  </item>
  <item>
    <title>Solving nonograms</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Nonograms.details</link>
    <description>
&lt;p&gt;In this post I will show how to solve nonograms automatically using a computer.
The code has been on &lt;a href=&quot;http://haskell.org/haskellwiki/Nonogram#Set_based_solver&quot;&gt;the Haskell wiki&lt;/a&gt; for over year, but I have never taken the time to explain how it works.&lt;/p&gt;&lt;p&gt;This post is literate haskell (&lt;a href=&quot;http://twan.home.fmf.nl/code/blog/haskell/Nonograms.lhs&quot;&gt;download the source here&lt;/a&gt;), so we need to start with some imports:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.Set&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;qualified&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.Map&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Map&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.Set&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt;)
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.List&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Control.Applicative&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Since we will be working with sets a lot, here are some additional utility functions:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;setAll&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;setAll&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pred&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;pred&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.toList&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unionMap&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unionMap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.unions&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.toList&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; The puzzle &lt;/h3&gt;&lt;p&gt;So, what is a nonogram anyway?
Quoting &lt;a href=&quot;http://en.wikipedia.org/wiki/Nonogram&quot;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;&lt;p&gt;Nonograms are picture logic puzzles in which cells in a grid have to be colored or left blank according to numbers given at the side of the grid to reveal a hidden picture. In this puzzle type, the numbers measure how many unbroken lines of filled-in squares there are in any given row or column. For example, a clue of &quot;4 8 3&quot; would mean there are sets of four, eight, and three filled squares, in that order, with at least one blank square between successive groups.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;A solved nonogram might look like the following image:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-lambda1.png&quot; style=&quot;vertical-align:middle;margin-left:2em;margin-top:3px;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;
A Haskell function to solve nonograms for us could have the following type, taking the clues for the rows and columns, and returning a grid indicating which squares are filled,&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;solvePuzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Values and cells &lt;/h3&gt;&lt;p&gt;For simplicity we will start with a single row.
A first idea is to represent the cells in a row as booleans, &lt;tt&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt;.
This works fine for a finished puzzle like:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row1.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;[3,4][.####.###]&quot;&gt;;&lt;br&gt;
but consider a partially solved row:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row2.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;[3,4][.#???.??#]&quot;&gt;.&lt;/p&gt;&lt;p&gt;First of all we will need a way to distinguish between blank cells (indicated by a cross) and unknown cells.
Secondly, we throw away a lot of information. For instance, we know that the last filled cell will be the last cell of a group of three.&lt;/p&gt;&lt;p&gt;To solve the second problem we can give each position an unique label, so the first filled cell will always be, for instance &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;/tt&gt;, the second one will be &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;/tt&gt;, etc.
For blank cells we can use negative numbers; the first group of blanks will be labeled &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;&lt;/tt&gt;, the second group will be &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;-2&lt;/span&gt;&lt;/tt&gt;, etc. Since the groups of blanks are of variable size, we give each one the same value.
Our solved row now looks like:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row1-labeled.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;[3 4][-1,2,3,4,5,-6,-6,7,8,9]&quot;&gt;.&lt;/p&gt;&lt;p&gt;In Haskell we can define the type of cell values as simply&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;deriving&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Since negative values encode empty cells, and positive values are filled cells, we can add some utility functions:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;blank&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;filled&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;blank&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
This still leaves the first issue, dealing with partially solved puzzles.&lt;/p&gt;&lt;h4&gt; Partial information &lt;/h4&gt;&lt;p&gt;When we don't know the exact value of a cell it is still possible that there is &lt;em&gt;some&lt;/em&gt; information.
For instance, we might know that the first cell will not contain the value &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;9&lt;/span&gt;&lt;/tt&gt;, since that value is already somewhere else. One way of representing this is to keep a set of possible values:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;An unknown cell is simply a cell containing all possible values, and the more we know about a cell, the less the set will contain.&lt;/p&gt;&lt;p&gt;At a higher level we can still divide cells into four categories:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Blank&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Filled&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Indeterminate&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Error&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;cellState&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;cellState&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.null&lt;/span&gt;      &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Error&lt;/span&gt;         &lt;span class=&quot;comment&quot;&gt;-- Something went wrong, no options remain&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setAll&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;blank&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Blank&lt;/span&gt;         &lt;span class=&quot;comment&quot;&gt;-- The cell is guaranteed to be blank&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setAll&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;filled&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Filled&lt;/span&gt;        &lt;span class=&quot;comment&quot;&gt;-- The cell is guaranteed to be filled&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;       &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Indeterminate&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;CellStates are convenient for displaying (partial) solution grids,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Blank&lt;/span&gt;         &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;.&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Filled&lt;/span&gt;        &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;#&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Indeterminate&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;?&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Error&lt;/span&gt;         &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;E&quot;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;For example, here is our running example again, this time rotated 90°.
The CellStates are shown on the left as before; while the actual &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;&lt;/tt&gt; set is on the right:&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row2-labeled.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;[3 4][-1,2,3,4,5,-6,-6,7,8,9]&quot;&gt;&lt;/p&gt;
&lt;h3&gt; Solving a single row &lt;/h3&gt;&lt;p&gt;Now it is time to solve a row.&lt;/p&gt;&lt;p&gt;As stated before, each filled cell gets a unique value.
From a clue of the group lengths we need to construct such a unique labeling,
such that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-6&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-6&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;7&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;8&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;9&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-10&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;-10&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt;.
The exact values don't matter, as long as they are unique and have the right sign.&lt;/p&gt;&lt;p&gt;Constructing this labeling is simply a matter of iterating over the clues,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt;' &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt;' &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt;' &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt;' (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This labeling gives us important &lt;em&gt;local information&lt;/em&gt;:
we know what values can occur before and after a particular value.
This is also the reason for including the negative (blank) values twice, since after a &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;&lt;/tt&gt; another &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;-1&lt;/span&gt;&lt;/tt&gt; can occur.&lt;/p&gt;&lt;p&gt;We can determine what comes after a value by zipping the labeling with its &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;tail&lt;/span&gt;&lt;/tt&gt;.
In our example:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;after    [-1,-1, 2, 3, 4, 5,-6,-6, 7, 8,  9, -10, -10]
comes [-1,-1, 2, 3, 4, 5,-6,-6, 7, 8, 9,-10, -10]&lt;/pre&gt;&lt;p&gt;
Collecting all pairs gives the mapping:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;{ -1 -&gt; {-1,2}, 2 -&gt; {3}, 3 -&gt; {4}, 4 -&gt; {5}, 5 -&gt; {-6}, -6 -&gt; {-6,7}, ...}&lt;/pre&gt;&lt;p&gt;Instead of carrying a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Map&lt;/span&gt;&lt;/tt&gt; around we can use a function that does the lookup in that map.
Of course we don't want to recalculate the map every time the function is called, so we need to be careful about sharing:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&lt;span class=&quot;varid&quot;&gt;bad1&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;    &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;Map.lookup&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;expensiveThing&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;bad2&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;    &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;Map.lookup&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theMap&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theMap&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;expensiveThing&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;good&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Map.lookup&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theMap&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;theMap&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;expensiveThing&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So for determining what comes after a value in the labeling:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mkAfter&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;mkAfter&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Map.findWithDefault&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.empty&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;afters&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;afters&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Map.fromListWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.union&lt;/span&gt;
                 &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zip&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.singleton&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;vs&lt;/span&gt;)&lt;/pre&gt;&lt;h4&gt; Row data type &lt;/h4&gt;&lt;p&gt;In the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;&lt;/tt&gt; datatype we put all the information we have:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; The cells in the row&lt;/li&gt;
&lt;li&gt; What values can come before and after a value&lt;/li&gt;
&lt;li&gt; The values at the edges&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
    { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;         &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    , &lt;span class=&quot;varid&quot;&gt;before&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;
    , &lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt;,  &lt;span class=&quot;varid&quot;&gt;end&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;
    }&lt;/pre&gt;&lt;p&gt;Some simple &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt;&lt;/tt&gt; instances:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;concatMap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;]&quot;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;To construct a row we first make a labeling for the clues.
Then we can determine what comes after each value, and what comes after each value in the reversed labeling (and hence comes before it in the normal order).&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mkRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mkRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;clue&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
        { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;replicate&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;width&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;Set.fromList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;)
        , &lt;span class=&quot;varid&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mkAfter&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;)
        , &lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mkAfter&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;
        , &lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.singleton&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;
        , &lt;span class=&quot;varid&quot;&gt;end&lt;/span&gt;    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.singleton&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;
        }
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;labeling&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;clue&lt;/span&gt;&lt;/pre&gt;&lt;h4&gt; Actually solving something &lt;/h4&gt;&lt;p&gt;Now all the things are in place to solve our row:
For each cell we can determine what values can come after it,
so we can filter the next cell using this information.
To be more precise, we can take the intersection of the set of values in a cell with the set of values that can occur after the previous cell.
In this way we can make a &lt;em&gt;forward&lt;/em&gt; pass through the row:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;solveBackward&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;newCells&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;) }
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;newCells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;    &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;newCells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;' &lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;newCells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;' &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;
              &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`Set.intersection`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;afterPrev&lt;/span&gt;
                    &lt;span class=&quot;varid&quot;&gt;afterPrev&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unionMap&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;prev&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Applying &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt;&lt;/tt&gt; to the example row above, we get&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row2-labeled.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;&quot;&gt;&lt;span style=&quot;padding:0 26px 12px 23px;margin:0 1em 0 0.4em;background:url(http://twan.home.fmf.nl/image/nonogram/arrow-right2.png) no-repeat bottom right;&quot;&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt;&lt;/tt&gt;&lt;/span&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row3-labeled.png&quot; style=&quot;vertical-align:middle;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;In much the same way we can do a &lt;em&gt;backwards&lt;/em&gt; pass.
Instead of duplicating the code from &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt;&lt;/tt&gt; it is easier to reverse the row, do a forward pass and then reverse the row again: &lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;solveBackward&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Where &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt;&lt;/tt&gt; reverses the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;&lt;/tt&gt; and swaps &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;before&lt;/span&gt;&lt;/tt&gt;/&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt;&lt;/tt&gt;/&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;end&lt;/span&gt;&lt;/tt&gt;: &lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
    { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;reverse&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;)
    , &lt;span class=&quot;varid&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;,   &lt;span class=&quot;varid&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;
    , &lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;end&lt;/span&gt;   &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;,   &lt;span class=&quot;varid&quot;&gt;end&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;start&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; }&lt;/pre&gt;&lt;p&gt;In the running example even more cells will be known after doing a backwards pass,&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row3-labeled.png&quot; style=&quot;vertical-align:middle;margin-left:2em;&quot; alt=&quot;&quot;&gt;&lt;span style=&quot;padding:0 26px 12px 23px;margin:0 1em 0 0.1em;background:url(http://twan.home.fmf.nl/image/nonogram/arrow-right2.png) no-repeat bottom right;&quot;&gt;&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;solveBackward&lt;/span&gt;&lt;/tt&gt;&lt;/span&gt;&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-row4-labeled.png&quot; style=&quot;vertical-align:middle;margin-right:-4em;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;These two steps together are as far as we are going to get with a single row, so let's package them up:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;solveRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;solveRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveBackward&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveForward&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;In the end we hopefully have a row that is completely solved,
or we might h
We can determine whether this is the case by looking at the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt;&lt;/tt&gt;s of the cells:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cellState&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;rowDone&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;rowFailed&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;rowDone&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Indeterminate&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;rowFailed&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Error&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt;&lt;/pre&gt;&lt;h4&gt; Human solution strategies &lt;/h4&gt;&lt;p&gt;By using just one single solution strategy we can in fact emulate most of the techniques humans use.
The &lt;a href=&quot;http://en.wikipedia.org/wiki/Nonogram&quot;&gt;Wikipedia page on nongrams&lt;/a&gt; lists several of these techniques. For instance, the &lt;em&gt;simple boxes&lt;/em&gt; technique is illustrated with the example:&lt;br&gt;
&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/en/9/9b/Paint_by_numbers_-_Solving_-_Example1.png&quot; style=&quot;vertical-align:middle;margin-left:2em; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;The Haskell program gives the same result:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveRow&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mkRow&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
[??######??]&lt;/pre&gt;&lt;p&gt;The reason why humans need many different techniques, while a single technique suffices for the program is that this simple technique requires a huge amount of administration. For each cell there is a while set of values, which would never fit into the small square grid of a puzzle.&lt;/p&gt;
&lt;h3&gt; The whole puzzle &lt;/h3&gt;&lt;p&gt;Just a single row, or even a list of rows is not enough.
In a whole nonogram there are clues for both the rows and the columns.
So, let's make a data type to hold both:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; }
    &lt;span class=&quot;keyword&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;And a function for constructing the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;&lt;/tt&gt; from a list of clues,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mkPuzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mkPuzzle&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowClues&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;colClues&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; 
    { &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;mkRow&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;colClues&lt;/span&gt;)) &lt;span class=&quot;varid&quot;&gt;rowClues&lt;/span&gt;
    , &lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;mkRow&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowClues&lt;/span&gt;)) &lt;span class=&quot;varid&quot;&gt;colClues&lt;/span&gt;
    }&lt;/pre&gt;&lt;p&gt;To display a puzzle we show the rows,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unlines&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;showList&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showString&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unlines&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Initially the puzzle grids are a bit boring, for example entering in GHCi&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mkPuzzle&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
[???]
[???]
[???]&lt;/pre&gt;&lt;p&gt;We already know how to solve a single row, so solving a whole list of rows is not much harder,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;stepRows&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;stepRows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveRow&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;) }&lt;/pre&gt;&lt;p&gt;Continuing in GHCi:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;stepRows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;previousPuzzle&lt;/span&gt;
[???]
[###]
[???]&lt;/pre&gt;&lt;p&gt;
To also solve the columns we can use the same trick as with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;reverseRow&lt;/span&gt;&lt;/tt&gt;, this time transposing the puzzle by swapping rows and columns.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;transposePuzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;transposePuzzle&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cols&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cols&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;But this doesn't actually help anything!
We still display only the rows, and what happens there is not affected by the values in the columns.
Of course when a certain cell in a row is filled (its &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;cellState&lt;/span&gt;&lt;/tt&gt; is &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Filled&lt;/span&gt;&lt;/tt&gt;), then we know that the cell in the corresponding column is also filled. We can therefore filter that cell by removing all blank values&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;filterCell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;filterCell&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Blank&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.filter&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;blank&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;filterCell&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Filled&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.filter&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;filled&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;filterCell&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;A whole row can be filtered by filtering each cell,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;filterRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;CellState&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;filterRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;states&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;filterCell&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;states&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;) }&lt;/pre&gt;&lt;p&gt;By transposing the list of states for each row we get a list of states for the columns.
With &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;filterRow&lt;/span&gt;&lt;/tt&gt; the column cells are then filtered.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;stepCombine&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;stepCombine&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;zipWith&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;filterRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;states&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;) }
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;states&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;transpose&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowStates&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
To solve the puzzle we apply &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;stepRows&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;stepCombine&lt;/span&gt;&lt;/tt&gt; alternatingly to the rows and to the columns.
When to stop this iteration?
We could stop when the puzzle is done, but not all puzzles can be solved this way.
A better aproach is to take the fixed point:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fixedPoint&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;step&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;step&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;step&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;transposePuzzle&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;stepCombine&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;stepRows&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The fixed point of a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; is the value &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt; such that &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt;.
Note that there are different fixed points, but the one we are interested in here is found by simply iterating &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;)&lt;/tt&gt;, ...&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;fixedPoint&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;fixedPoint&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fx&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fixedPoint&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fx&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fx&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The tiny 3*3 example can now be solved:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;previousPuzzle&lt;/span&gt;
[.#.]
[###]
[.#.]&lt;/pre&gt;&lt;p&gt;But for other puzzles, such as the letter lambda from the introduction, we have no such luck:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;lambdaPuzzle&lt;/span&gt;
[??????????]
[??????????]
...&lt;/pre&gt;
&lt;h4&gt; Guessing &lt;/h4&gt;&lt;p&gt;To solve more difficult puzzles the direct reasoning approach is not enough.
To still solve these puzzles we need to make a &lt;em&gt;guess&lt;/em&gt;, and backtrack if it is wrong.&lt;/p&gt;&lt;p&gt;Note that there are puzzles with more than one solution, for example&lt;br&gt;
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-grid1.png&quot; style=&quot;vertical-align:middle;margin-left:2em;margin-right:1em;margin-top:2px;&quot; alt=&quot;&quot;&gt;and
&lt;img src=&quot;http://twan.home.fmf.nl/image/nonogram/nonogram-grid2.png&quot; style=&quot;vertical-align:middle;margin-left:1em;margin-top:2px;&quot; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;To find &lt;em&gt;all&lt;/em&gt; solutions, and not just the first one, we can use the list monad.&lt;/p&gt;&lt;p&gt;
To make a guess we can pick a cell that has multiple values in its set, and for each of these values see what happens if the cell contains just that value.
Since there are many cells in a puzzle there are also many cells to choose from when we need to guess. It is a good idea to pick the &lt;em&gt;best one&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;For picking the best alternative a pair of a value and a &lt;em&gt;score&lt;/em&gt; can be used:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; }&lt;/pre&gt;&lt;p&gt;This data type is an applicative functor if we use &lt;tt&gt;&lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;&lt;/tt&gt; as a default score:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Functor&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Applicative&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;*&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`min`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;When there are alternatives we want to pick the best one, the one with the highest score:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Alternative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Alternative&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;empty&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;empty&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;minBound&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;|&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
            &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;           &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now given a list we can apply a function to each element, but change only the best one.
This way we can find the best cell to guess and immediately restrict it to a single alternative.
We can do this by simply enumerating all ways to change a single element in a list.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Alternative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt;  (&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;         &lt;span class=&quot;comment&quot;&gt;-- change x and keep the tail&lt;/span&gt;
                 &lt;span class=&quot;varop&quot;&gt;&amp;lt;|&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;&amp;lt;$&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- change the tail and keep x&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This can also be generalized to &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;&lt;/tt&gt;s and whole &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;&lt;/tt&gt;s:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;mapBestRow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Alternative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Row&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mapBestRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setCells&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setCells&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;row&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cells&lt;/span&gt;' }

&lt;span class=&quot;varid&quot;&gt;mapBestRows&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Alternative&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;mapBestRows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setRows&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mapBest&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;mapBestRow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;setRows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt;' }&lt;/pre&gt;&lt;p&gt;
What is the best cell to guess?
A simple idea is to use the cell with the most alternatives, in the hope of eliminating as many of them as soon as possible. Then the score of a cell is the size of its set.
The alternatives are a singleton set for each value in the cell.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;guessCell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Cell&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;guessCell&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Scored&lt;/span&gt;
    { &lt;span class=&quot;varid&quot;&gt;best&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.singleton&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.toList&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cell&lt;/span&gt;
    , &lt;span class=&quot;varid&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;Set.size&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cell&lt;/span&gt; }&lt;/pre&gt;&lt;p&gt;We can now make a guess by taking the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;best&lt;/span&gt;&lt;/tt&gt; way to apply &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;guessCell&lt;/span&gt;&lt;/tt&gt; to a single cell:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mapBestRows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;guessCell&lt;/span&gt;&lt;/pre&gt;&lt;h4&gt; Putting it together &lt;/h4&gt;&lt;p&gt;Direct solving is &lt;em&gt;much&lt;/em&gt; faster than guess based solving.
So the overall strategy is to use &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt;&lt;/tt&gt;, and when we get a puzzle that is not &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt;&lt;/tt&gt; we do a single guess, and then continue with direct solving all alternatives:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;solve&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;solve&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;failed&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt;   &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;'&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;otherwise&lt;/span&gt;      &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;concatMap&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;')
  &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;' &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solveDirect&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;failed&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt;   &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowDone&lt;/span&gt;   (&lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;failed&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;rowFailed&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;puzzle&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Finally we can solve the lambda puzzle!&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;lambdaPuzzle&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;mkPuzzle&lt;/span&gt;
    &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;Nonograms&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;solve&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;lambdaPuzzle&lt;/span&gt;
[.##.......]
[#.##......]
[#..#......]
[...##.....]
[....#.....]
[...###....]
[...###....]
[..##.##...]
[..##..#...]
[.##...##.#]
[.##....###]
[##.....##.]&lt;/pre&gt;
</description>
  </item>
  <item>
    <title>Simple reflection of expressions</title>
    <link>http://twan.home.fmf.nl/blog/haskell/simple-reflection-of-expressions.details</link>
    <description>&lt;p&gt;
This blog post is inspired by a message from Cale on #haskell yesterday.
He came up with an amazing way to show how &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;/span&gt;&lt;/tt&gt; work:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&amp;lt;Cale&gt;      &gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&quot;(f &quot;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot; &quot;&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;) &lt;span class=&quot;str&quot;&gt;&quot;z&quot;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;)
&lt;span class=&quot;input&quot;&gt;&amp;lt;lambdabot&gt; &lt;/span&gt;&lt;span class=&quot;str&quot;&gt;&quot;(f 1 (f 2 (f 3 (f 4 (f 5 z)))))&quot;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;While the output looks great, the call itself could be clearer, especially for beginners.
Through a combination of overloading and small hacks it is possible to get the same result with a much nicer expression,&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
f 1 (f 2 (f 3 (f 4 (f 5 x))))&lt;/pre&gt;&lt;h3&gt; Let's get started &lt;/h3&gt;&lt;p&gt;I will call this module &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;SimpleReflect&lt;/span&gt;&lt;/tt&gt;, since this is a poor mans form of reflection, converting code back to expressions at run time.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;SimpleReflect&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Our results will be 'expressions'.
All we need to do with expressions is &lt;em&gt;show&lt;/em&gt; them, convert them to strings.&lt;/p&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt;&lt;/tt&gt; class has a function &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;showsPrec&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;ShowS&lt;/span&gt;&lt;/tt&gt; for converting a value of type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; to a string.
The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;ShowS&lt;/span&gt;&lt;/tt&gt; type improves the performance compared to using strings; the integer is used for putting parentheses in the right places.
But none of this matters for now,
we will just emulate that behavior for our expression type:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;ShowS&lt;/span&gt; }&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;showsPrec&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The things like &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt; will be &lt;em&gt;variables&lt;/em&gt; these are just strings. Showing strings is easy,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showString&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; }&lt;/pre&gt;&lt;p&gt;In fact, we can show all kinds of values, for instance numbers.
So we could make a function that &lt;em&gt;lifts&lt;/em&gt; any showable value to an expression:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showsPrec&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; }&lt;/pre&gt;&lt;p&gt;While this is almost identical to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt;&lt;/tt&gt;, it is not the same,
because the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt;&lt;/tt&gt; instance for &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt;&lt;/tt&gt; is not the same as &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;showString&lt;/span&gt;&lt;/tt&gt;. Compare:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;x&quot;&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;x&quot;&lt;/span&gt;
&lt;span class=&quot;str&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; From variables to functions &lt;/h3&gt;&lt;p&gt;In your average piece of source code multiple expressions are combined with operators.
The most common operator is function application, written with just whitespace.
Each Haskell operator has a &lt;em&gt;precedence level&lt;/em&gt;, indicating how tight that operator binds to its arguments.&lt;/p&gt;&lt;p&gt;In this blog post we only deal with left associative operators, which means that the left sub-expressions is printed with the same precedence level.
A simple combinator for operators is then:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;prec&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showFun&lt;/span&gt; }
 &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showFun&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showParen&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;prec&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt;
                   &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;prec&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showString&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;showExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;prec&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;We would like to be able to use variables like &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; as if they were functions, so this &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; has to have the type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;/tt&gt;, or &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;/tt&gt;, etc.
This can be done with type classes. The class &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt;&lt;/tt&gt; defines what things we can use expressions for:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Obviously expressions are themselves expressions,&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromExpr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Any expression can also be used as a function.
As stated above function application is the operator &lt;tt&gt;&lt;span class=&quot;str&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;/tt&gt;;
it has precedence level 10, higher than any real operator.
To be as generic as possible we can &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt;&lt;/tt&gt; any showable argument to an expression.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromExpr&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;With &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt;&lt;/tt&gt; in place we can make more generic variables that can be used as any function type:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromExpr&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;With all this in place Cale's &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt; example can now be written as&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;f&quot;&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;x&quot;&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
f 1 (f 2 (f 3 (f 4 (f 5 x))))&lt;/pre&gt;&lt;h3&gt; Lifting the alphabet &lt;/h3&gt;&lt;p&gt;To write even shorter examples a slightly evil idea is to simply define 26 variables,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;There is a minor problem with this idea, which will become apparent once you try it out:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;*SimpleReflect&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;

&amp;lt;interactive&gt;:1:8:
    Ambiguous type variable `b' in the constraints:
      `FromExpr b' arising from a use of `x' at &amp;lt;interactive&gt;:1:8
      `Show b' arising from a use of `f' at &amp;lt;interactive&gt;:1:6
    Probable fix: add a type signature that fixes these type variable(s)&lt;/pre&gt;&lt;p&gt;The compiler doesn't know what the type of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt; should be.
It is only used as an argument to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt;, but that can be any &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Show&lt;/span&gt;&lt;/tt&gt;able type.
In the future we might be able to write &lt;tt&gt;&lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;/tt&gt; (&lt;a href=&quot;http://hackage.haskell.org/trac/haskell-prime/wiki/Defaulting&quot;&gt;see the Haskell' wiki&lt;/a&gt;),
but until then we will have to do something else.&lt;/p&gt;&lt;p&gt;Since usually the names &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt;&lt;/tt&gt;, etc. are used for functions,
I chose to only overload those, and make the rest simple variables:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;k&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;o&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;q&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;t&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;
&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;j&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;k&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;l&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;m&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;o&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;p&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;q&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;t&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;u&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;v&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;w&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;chr&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;chr&quot;&gt;'i'&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;chr&quot;&gt;'z'&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FromExpr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;f&quot;&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;g&quot;&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;h&quot;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;With our 26 new top level names we can finally the original example in a natural way,&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
f 1 (f 2 (f 3 (f 4 (f 5 x))))&lt;/pre&gt;&lt;h3&gt; Lifting numbers (a.k.a. lots-of-instances) &lt;/h3&gt;&lt;p&gt;All this work for just &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldr&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;foldl&lt;/span&gt;&lt;/tt&gt; seems like a bit of a waste of time.
To make things a little bit more interesting we could also add support for numeric operations.
Then we can write&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;
0 + 1 + 2 + 3 + 4 + 5&lt;/pre&gt;&lt;p&gt;To do this we need to define instances of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Enum&lt;/span&gt;&lt;/tt&gt;.
The first of these is not very hard, but we need &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt;&lt;/tt&gt; and later &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt;&lt;/tt&gt; instances as well.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt;&lt;/tt&gt; class has two functions of type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;, which is where we can do something interesting:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ord&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;compare&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;compare&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;min&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;max&quot;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now we get &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;minimum&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;min&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;z&lt;/span&gt;&lt;/tt&gt; for free.&lt;/p&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt;&lt;/tt&gt; class has some operators.
The mechanism for defining does is already in place, so this class should be simple:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;)    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; + &quot;&lt;/span&gt;
    (&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;)    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; - &quot;&lt;/span&gt;
    (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;)    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; * &quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;negate&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;abs&lt;/span&gt;    &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;abs&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;signum&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;signum&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;To write &lt;tt&gt;&lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;/tt&gt; needs to be an instance of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Enum&lt;/span&gt;&lt;/tt&gt;.
Here we bump into a bit of a problem, how do we enumerate expressions?&lt;/p&gt;&lt;p&gt;Well, I will cheat a bit, and read out the expression as an integer.
This operation is the inverse of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;lift&lt;/span&gt;&lt;/tt&gt;, let's call it &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;unlift&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;unlift&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Read&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;unlift&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;expr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;read&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;expr&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Conversion to &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Integers&lt;/span&gt;&lt;/tt&gt; is usually done with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt;&lt;/tt&gt; from the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Integral&lt;/span&gt;&lt;/tt&gt;, so we add an instance for that as well.
We need a &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Real&lt;/span&gt;&lt;/tt&gt; instance first:&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Real&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;toRational&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;toRational&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integral&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;unlift&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;quot&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; `quot` &quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;rem&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; `rem` &quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;div&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; `div` &quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;mod&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot; `mod` &quot;&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;-- someone forgot a default :(&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;quotRem&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;quot&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;rem&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;divMod&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;div&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;, &lt;span class=&quot;varid&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Finally the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Enum&lt;/span&gt;&lt;/tt&gt; class. As I already said, the actual enumeration can be handled by going through &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Enum&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;succ&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;succ&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;pred&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;pred&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;toEnum&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;toEnum&quot;&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;fromEnum&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromEnum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt;
    &lt;span class=&quot;varid&quot;&gt;enumFrom&lt;/span&gt;       &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;enumFrom&lt;/span&gt;       (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;enumFromThen&lt;/span&gt;   &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;enumFromThen&lt;/span&gt;   (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;enumFromTo&lt;/span&gt;     &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;   &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;enumFromTo&lt;/span&gt;     (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)        (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)
    &lt;span class=&quot;varid&quot;&gt;enumFromThenTo&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fromInteger&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;enumFromThenTo&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;toInteger&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- just to fit in the page layout of the blog&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Playing a bit &lt;/h3&gt;&lt;p&gt;None of the above was terribly complicated, just a lot of boilerplate code.
What can we do with such a well-plated boiler?
Here are some examples:&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;map&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
0 + 1 * x + 2 * x + 3 * x + 4 * x + 5 * x&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;iterate&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
[x, x * x, x * x * (x * x), x * x * (x * x) * (x * x * (x * x)), ...&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;scanl&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
[x, f x a, f (f x a) b, f (f (f x a) b) c]&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;zipWith3&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;num&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Expr&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;
[f 1 1 1, f 2 3 4, f 3 5 7, f 4 7 10, f 5 9 13, f 6 11 16, ...&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Coming soon to a lambdabot near you.&lt;/em&gt;&lt;/p&gt;</description>
  </item>
  <item>
    <title>References, Arrows and Categories</title>
    <link>http://twan.home.fmf.nl/blog/haskell/References-Arrows-and-Categories.details</link>
    <description>
&lt;h3&gt;Recap: functional references&lt;/h3&gt;&lt;p&gt;Last time (okay, it was over two months ago) I talked about
&lt;a href=&quot;http://twan.home.fmf.nl/blog/haskell/overloading-functional-references.details&quot;&gt;overloading functional references&lt;/a&gt; so that they can be used both as regular functions and as references.
The data type of references I used was
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;
      }&lt;/pre&gt;&lt;p&gt;
While I arrived at the type class,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
This provides 'construction' and 'composition'.&lt;/p&gt;
&lt;h3&gt;Arrows&lt;/h3&gt;&lt;p&gt;The class parameter &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt;&lt;/tt&gt; has kind &lt;tt&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;/tt&gt;, meaning it takes two types and 'evaluates' to a type.
If you are familiar with the Haskell libraries you may know there is a similar class who's parameter also has kind &lt;tt&gt;&lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;*&lt;/span&gt;&lt;/tt&gt;,
called &lt;a href=&quot;http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#t%3AArrow&quot;&gt;Arrow&lt;/a&gt;.
There is an instance &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;)&lt;/tt&gt;, just like there I defined an instance &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;)&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;According to the &lt;a href=&quot;http://haskell.org/arrows/&quot;&gt;arrows webpage&lt;/a&gt;, &lt;em&gt;&quot;Arrows are a new abstract view of computation&quot;&lt;/em&gt;.
This raises the question: Can we combine these ideas? Are functional references arrows?&lt;/p&gt;&lt;p&gt;That Arrow class looks like
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;&gt;&gt;&gt;&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;
      &lt;span class=&quot;comment&quot;&gt;-- some more stuff&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
If you look closely, &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;&gt;&gt;&gt;&lt;/span&gt;)&lt;/tt&gt; is just &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;)&lt;/tt&gt; with the arguments reversed.
What about &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt;&lt;/tt&gt;? &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt;&lt;/tt&gt; should turn any function into a reference.
But references need a way to transform the result back to be able to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt;&lt;/tt&gt; the new value.&lt;/p&gt;&lt;p&gt;Clearly this is &lt;em&gt;not going to work&lt;/em&gt;. The problem is that Arrows are not general enough!&lt;/p&gt;
&lt;h3&gt;The easy fix&lt;/h3&gt;&lt;p&gt;
What we need here is to make &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt;&lt;/tt&gt; a &lt;em&gt;super&lt;/em&gt;class of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt;.
All current &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt;s can implement &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;)&lt;/tt&gt;, since it is the same as &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;&gt;&gt;&gt;&lt;/span&gt;)&lt;/tt&gt;.
To implement &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt;&lt;/tt&gt; an arrow just ignores the setter, then &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt;&lt;/tt&gt; becomes the same as &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;Okay, we're done.&lt;/p&gt;&lt;p&gt;Except that we will have &lt;em&gt;the same problem&lt;/em&gt; again the next time someone wants to generalize Arrows.
It would be much better to fix it once and for all.&lt;/p&gt;
&lt;h3&gt;Categories&lt;/h3&gt;&lt;p&gt;
The most basic idea behind arrows comes from category theory &lt;sup&gt;&lt;a href=&quot;#cattheory&quot; style=&quot;text-decoration:none;&quot;&gt;&amp;dagger;&lt;/a&gt;&lt;/sup&gt;.
An 'arrow' or 'morphism' is a connection between two objects from a 'category', in this case two Haskell types.
Usually the category we are interested in is &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Hask&lt;/span&gt;&lt;/tt&gt;, &lt;a href=&quot;http://en.wikibooks.org/wiki/Haskell/Category_theory&quot;&gt;the category of Haskell functions&lt;/a&gt;.
In &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Hask&lt;/span&gt;&lt;/tt&gt; a 'morphism' between two types &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt; is just a function from type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; to type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;, so a function of type &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;An &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt; is nothing more than a &lt;em&gt;different&lt;/em&gt; category.
The types are still the same, but instead of a function we get something else for the morphisms.&lt;/p&gt;&lt;p&gt;If you look up the &lt;a href=&quot;http://en.wikipedia.org/wiki/Category_%28mathematics%29&quot;&gt;definition of a category&lt;/a&gt; you will find that in general only two things are required of morphism:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; There is an identity morphism.&lt;/li&gt;
&lt;li&gt; Morphisms can be composed.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Unlike the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt; type class, there is nothing saying that the morphisms have to correspond to functions.
For instance using the reverse arrow, &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;&amp;lt;-&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;flip&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;)&lt;/tt&gt;, as the morphisms gives is a perfectly valid category.
So does the something as strange as &lt;tt&gt;&lt;span class=&quot;keyword&quot;&gt;newtype&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Integer&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;If you look at the above definition of a category, it immediately leads to a Haskell type class
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Which is a generalization of both &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt;.
So it turns out that the only essential component we are left with is the composition operator.
Everything else was relating the category to Haskell functions or references.&lt;/p&gt;&lt;p&gt;Category theory comes with a small set of laws as well:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;  &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;  &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;h&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;h&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
In other words, composing with the identity function does nothing, 
and composition is associative. Great!&lt;/p&gt;
&lt;h3&gt;Making it useful again&lt;/h3&gt;&lt;p&gt;
Now that we have kicked &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt;&lt;/tt&gt; and friends out of the type class lots of types can become instances.
On the other hand, the class itself has become pretty useless.&lt;/p&gt;&lt;p&gt;Before going to functional references there is a more general notion, invertible functions.
These are discussed in relation to arrows in &lt;a href=&quot;http://www.cs.ru.nl/A.vanWeelden/bi-arrows/&quot;&gt;&quot;There and back again: arrows for invertible programming&quot;&lt;/a&gt;.
The only way to be sure that a function is invertible is to give its inverse. In a data type that could look like
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Invertible&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Invertible&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;forward&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;backward&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
      }&lt;/pre&gt;&lt;p&gt;To put that in the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt;/&lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt;&lt;/tt&gt; framework we can add a subclass &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt;&lt;/tt&gt;.
It is similar to the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt;&lt;/tt&gt; class, only for invertible functions instead of references.
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;arrInv&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;~~&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
      
      &lt;span class=&quot;comment&quot;&gt;-- We get a default implementation for id.&lt;/span&gt;
      &lt;span class=&quot;comment&quot;&gt;-- Note that this is not valid Haskell, we would need something like &lt;a href=&quot;http://repetae.net/john/recent/out/classalias.html&quot;&gt;class aliases&lt;/a&gt;.&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;arrInv&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;) (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;What does it mean if a type/category is an instance of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt;&lt;/tt&gt;?
It means that that category &lt;em&gt;contains all invertible functions&lt;/em&gt;.
Read this statement carefully.
An &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt;&lt;/tt&gt; does not mean that morphisms in the category are invertible, but that invertible functions can be turned into morphisms.&lt;/p&gt;&lt;p&gt;With &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt;&lt;/tt&gt; we already get all kinds of interesting morphisms, for example
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;negate&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
(&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt;, &lt;span class=&quot;conid&quot;&gt;Num&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;negate&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- increment the negation by 1, so decrement by one&lt;/span&gt;
&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; (&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- find a value x such that 3+x == 4&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This last example is a bit ugly, because we use function references.
It will look better if we use the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Invertible&lt;/span&gt;&lt;/tt&gt; type.
The function similar to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt;&lt;/tt&gt; is &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;inverse&lt;/span&gt;&lt;/tt&gt;:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- Get the inverse of an invertible function&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;inverse&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Invertible&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;inverse&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;arrInv&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;backward&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;forward&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;i&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;
Now we can write the above example without &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;undefined&lt;/span&gt;&lt;/tt&gt;:
&lt;/p&gt;&lt;pre class=&quot;ghci&quot;&gt;&lt;span class=&quot;input&quot;&gt;&gt; &lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;inverse&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;) &lt;span class=&quot;num&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;To references and beyond&lt;/h3&gt;&lt;p&gt;
Inverses are nice, but we haven't got references yet.
There is no way to define &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;For that we really need the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt;&lt;/tt&gt; class, or in this arrow framework, &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt;&lt;/tt&gt;:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;arrRef&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
      
      &lt;span class=&quot;comment&quot;&gt;-- A default implementation of @arrInv@&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;arrInv&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;arrRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Like with &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt;&lt;/tt&gt;, if a category type is an instance of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt;&lt;/tt&gt;, it means that that category contains all functional references.&lt;/p&gt;&lt;p&gt;Finally, the least restrictive class is the regular old &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt;,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
      
      &lt;span class=&quot;varid&quot;&gt;arrRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;To summarize, we now have a class hierarchy that looks like
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;InvArrow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt;The rest of the &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt; class&lt;/h3&gt;&lt;p&gt;
If you look back to the definition of &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt; I gave above, you will see
&lt;/p&gt;&lt;pre&gt;      &lt;span class=&quot;comment&quot;&gt;-- some more stuff&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Besides lifting (&lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;arr&lt;/span&gt;&lt;/tt&gt;) and composition (&lt;tt&gt;&lt;span class=&quot;varop&quot;&gt;&gt;&gt;&gt;&lt;/span&gt;&lt;/tt&gt;) the &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base-3.0.0.0/Control-Arrow.html#t%3AArrow&quot;&gt;standard Arrow class&lt;/a&gt; also
defines combinators for working with tupled values.&lt;/p&gt;&lt;p&gt;We could put these in the new &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Arrow&lt;/span&gt;&lt;/tt&gt; class, but they might also be useful for types which are not full arrows.
Like, say, functional references.&lt;/p&gt;&lt;p&gt;The most flexible thing to do is to put this functionality in yet another class.
For working with pairs we can define
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;CategoryPair&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;first&lt;/span&gt;  &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;)
      &lt;span class=&quot;varid&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;)
      (&lt;span class=&quot;varop&quot;&gt;***&lt;/span&gt;)  &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;d&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;There are some tricky issues to work out,
but this post is already five pages long.&lt;/p&gt;&lt;p&gt;I am going to stop here. Pairs, sum types, fixed points, monoids and duality all will have to wait until next time.&lt;/p&gt;
&lt;h3&gt;The code&lt;/h3&gt;&lt;p&gt;
That was a long story, and I even stopped way before the end and skipped the instances.&lt;/p&gt;&lt;p&gt;The generalized arrow/category framework is growing into a useful library that hopefully someday can become part of the base libraries.
I have decided to put the code somewhere. In this case, somewhere is
&lt;/p&gt;   &lt;pre&gt;darcs get &lt;a href=&quot;http://code.haskell.org/category&quot;&gt;http://code.haskell.org/category&lt;/a&gt;&lt;/pre&gt;&lt;p&gt;As the name suggests, this library is not just for functional references.
Rather it contains the whole &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Category&lt;/span&gt;&lt;/tt&gt; framework. The &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;&lt;/tt&gt; type is just a bonus.&lt;/p&gt;&lt;p&gt;The library also contains code for deriving &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;RefArrow&lt;/span&gt;&lt;/tt&gt; functions for record fields, courtesy to omnId.&lt;/p&gt;&lt;p&gt;
&lt;b&gt;footnotes&lt;/b&gt;&lt;br&gt;
&lt;a name=&quot;cattheory&quot;&gt;&amp;dagger;&lt;/a&gt;: I am in no way a category theory expert; Category theorists feel free to hate me for abuse of terminology and incorrect explanations.
In particular, the type constructor &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;cat&lt;/span&gt;&lt;/tt&gt; is not really the category itself, just like the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; in &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; is not really a functor. But it is the closest thing we have got.&lt;/p&gt;</description>
  </item>
  <item>
    <title>Overloading functional references</title>
    <link>http://twan.home.fmf.nl/blog/haskell/overloading-functional-references.details</link>
    <description>&lt;p&gt;
Recently there have been some &lt;a href=&quot;http://luqui.org/blog/archives/2007/08/05/&quot;&gt;blog post&lt;/a&gt;
and &lt;a href=&quot;http://article.gmane.org/gmane.comp.lang.haskell.cafe/28094&quot;&gt;mailing list messages&lt;/a&gt;
about &quot;functional references&quot;. In this message I will look into ways to improve upon that concept.&lt;/p&gt;&lt;p&gt;The above links should give you an idea of what a functional reference is, but I will explain it here in my own words.
You can skip this introduction if you already know what functional references are.&lt;/p&gt;&lt;h3&gt; What are functional references? &lt;/h3&gt;&lt;p&gt;A functional reference is a data structure that can be used to update parts of another structure,
it is a &lt;em&gt;reference&lt;/em&gt; into that structure.
We need a way to &lt;em&gt;get&lt;/em&gt; the part, and a way to replace the part by &lt;em&gt;set&lt;/em&gt;ting it to something else.
This leads to the data type:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;
      }&lt;/pre&gt;&lt;p&gt;
Now &lt;tt&gt;&lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; represents a reference to an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;/tt&gt; inside an &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;&lt;/tt&gt; structure.&lt;/p&gt;&lt;p&gt;One of the simplest possible (non-trivial) references is that to the first part of a pair:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;(&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;_&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;,&lt;span class=&quot;varid&quot;&gt;y&lt;/span&gt;)
      }&lt;/pre&gt;&lt;p&gt;
Having defined this, we can use it to access and modify pairs, for example
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&gt; get fst (1,2)
1
&gt; set fst 3 (1,2)
(3,2)&lt;/pre&gt;&lt;p&gt;
You can read this as &quot;get the first part of ...&quot; and &quot;set the first part to 3 in ...&quot;.&lt;/p&gt;&lt;p&gt;Another useful function is &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt;&lt;/tt&gt;,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;)) &lt;span class=&quot;varid&quot;&gt;s&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
Update gets the value, applies a function, and sets it again.
This allows us to 'map' functions over parts of data structures:
&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&gt; update fst (+1) (1,2)
(2,2)&lt;/pre&gt;&lt;p&gt;The real power of functional references lies in their composability.
Like functions, we can compose two references to give a new one
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bc&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ab&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bc&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ab&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ab&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bc&lt;/span&gt;
      }&lt;/pre&gt;&lt;p&gt;We can now modify nested pairs:&lt;/p&gt;&lt;pre class=&quot;nocode&quot;&gt;&gt; update (fst `compose` fst) (*2) ((3,4),5)
((6,4),5)&lt;/pre&gt;
  
&lt;h3&gt; Use case: records &lt;/h3&gt;&lt;p&gt;The place where these references shine is with records.
Say we have the following data type:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Employee&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;name&lt;/span&gt;   &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Int&lt;/span&gt;
      }&lt;/pre&gt;&lt;p&gt;
It would be great if &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;name&lt;/span&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt;&lt;/tt&gt; where references,
then we could simply say
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;giveRaise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;100&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;
This shouldn't be too hard to automate with &lt;a href=&quot;http://www-users.cs.york.ac.uk/~ndm/derive/&quot;&gt;Data.Derive&lt;/a&gt;, the functions would look like
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;name_&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;name_&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; }
      }&lt;/pre&gt;&lt;p&gt;
Or better yet, we could specify references as the default behavior in the next Haskell standard!&lt;/p&gt;&lt;p&gt;There is a problem, however, when we have defined the record accessors to be references.
Take the normally legal code
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;johnsSallary&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;john&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
This is no longer valid, since salary is not a function. Instead we must write
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;johnsSallary&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;john&lt;/span&gt;&lt;/pre&gt;&lt;h3&gt; Type classes to the rescue &lt;/h3&gt;&lt;p&gt;Fortunately there is a clean solution to this problem using type classes.
We can define the type class
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
We can define an instance for functional references,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
As well as for functions
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The record accessors can now be defined as
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;name_&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;e&lt;/span&gt; { &lt;span class=&quot;varid&quot;&gt;name_&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;n&lt;/span&gt; })&lt;/pre&gt;&lt;p&gt;And all is well again:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;giveRaise&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;100&lt;/span&gt;)
&lt;span class=&quot;varid&quot;&gt;johnsSallary&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;john&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;While we are at it, we could also add the &lt;tt&gt;(&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;)&lt;/tt&gt; operator to the class,
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;FRef&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;compose&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Ref&lt;/span&gt; (&lt;span class=&quot;varop&quot;&gt;-&gt;&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
      &lt;span class=&quot;varid&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt;
      (&lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt;) &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;conid&quot;&gt;Prelude&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;..&lt;/span&gt;) &lt;span class=&quot;comment&quot;&gt;-- the (.) from the prelude&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
now
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;giveRaiseToFirst&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;update&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;salary&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;fst&lt;/span&gt;) (&lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;num&quot;&gt;100&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;
Gives a raise to the first employee in a pair.&lt;/p&gt;&lt;h3&gt; Concluding remarks &lt;/h3&gt;&lt;p&gt;Note that all this is perfectly valid Haskell 98 code, no extensions are needed.
This means that it should not be hard to add such references to the language standard.&lt;/p&gt;&lt;p&gt;There are many more neat things you can do with functional references, but I will save that for another time.&lt;/p&gt;</description>
  </item>
  <item>
    <title>Knuth-Morris-Pratt in Haskell</title>
    <link>http://twan.home.fmf.nl/blog/haskell/Knuth-Morris-Pratt-in-Haskell.details</link>
    <description>&lt;p&gt;A request that comes up regularly on the Haskell mailing list is for a function to determine whether one string
(the needle) is a substring of another one (the haystack).
While there is no such function in the Haskell standard library&lt;sup&gt;&lt;a href=&quot;#infixof&quot; style=&quot;text-decoration:none;&quot;&gt;&amp;dagger;&lt;/a&gt;&lt;/sup&gt;, it is easy enough to implement:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Data.List&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isSubstringOf`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isPrefixOf`&lt;/span&gt;) (&lt;span class=&quot;varid&quot;&gt;tails&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;
Unfortunatly, this function has a worst case time complexity of &lt;span class=&quot;math&quot;&gt;O(length as * length bs)&lt;/span&gt;.
For example if we evaluate
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;str&quot;&gt;&quot;aaaaaaaaaab&quot;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isSubstringOf`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;replicate&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
We will first match 10 characters starting from the first position and fail just before we matched the entire string.
Then, starting from the second position, we will match 10 characters again, etc. In total we we will do &lt;span class=&quot;math&quot;&gt;11 * 100 = O(length as * length bs)&lt;/span&gt; comparisons.&lt;/p&gt;&lt;p&gt;There exists an algorithm called the &lt;a href=&quot;http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm&quot;&gt;Knuth-Morris-Pratt string searching algorithm&lt;/a&gt;
which has a much better, &lt;code&gt;&lt;em&gt;O(length as + length bs)&lt;/em&gt;&lt;/code&gt;, worst case behavior.
Unfortunately all descriptions you find of the algorithm rely on building a table, and using random access patterns on it.
Not only does this make it impossible to use simple data structures like lists, it also obfuscates the underlying idea.&lt;/p&gt;
&lt;h3&gt; The idea &lt;/h3&gt;&lt;p&gt;The core idea of the algorithm is that we only want to process each character of both strings once.
This is done by building a table from the needle, and using that table to determine what should be done after each character of the haystack.
Either the entire needle has been matched at that point and we are done, or we get a new position in the table to use for the next character.&lt;/p&gt;&lt;p&gt;So, let's turn the above description into a Haskell datatype!
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt;
      { &lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
      , &lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;)
      }&lt;/pre&gt;&lt;p&gt;Clearly, if we know how to make such a 'table' the matching process is straight forward.
We need to apply &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt;&lt;/tt&gt; to each character and we want to know if any of the intermediate tables are &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt;&lt;/tt&gt;:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;isSubstringOf2&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;isSubstringOf2&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;match&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;
   &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;match&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;b&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
This can be made shorter using functions from the Prelude:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;isSubstringOf3&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;scanl&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt;) &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt; Making the table &lt;/h3&gt;&lt;p&gt;All that is left is to make a table, constructing it using a simple recursive function is not an option
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;makeTable1&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;makeTable1&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;True&lt;/span&gt;  &lt;span style=&quot;color:red&quot;&gt;undefined?&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;makeTable1&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;makeTable1&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;Because what do we do if we &lt;em&gt;don't&lt;/em&gt; have a match?
Let's look at an example, the calculation &lt;tt&gt;&lt;span class=&quot;str&quot;&gt;&quot;abc&quot;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isSubstringOf`&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;aabc&quot;&lt;/span&gt;&lt;/tt&gt; would go something like:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;abc&quot;&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table0&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table0&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table0&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;) &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'b'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table2&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;) &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt;
                &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- what to do now?&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;
What we should do, is start over, but dropping the first character from the input, in this case that gives
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;comment&quot;&gt;-- start over, now for &quot;abc&quot; `isSubstringOf` &quot;abc&quot;&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table0&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;) &lt;span class=&quot;chr&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table1&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'b'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'b'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table2&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;) &lt;span class=&quot;chr&quot;&gt;'b'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table2&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table2&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table2&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'b'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;keyglyph&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;chr&quot;&gt;'c'&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table3&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color:red&quot;&gt;????&lt;/span&gt;) &lt;span class=&quot;chr&quot;&gt;'c'&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table3&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table3&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:green&quot;&gt;True&lt;/span&gt;&lt;/pre&gt;
&lt;h3&gt; The trick &lt;/h3&gt;&lt;p&gt;At first glance it would seem that we have to reexamine parts of the haystack when we start over.
But this is not the case.&lt;/p&gt;&lt;p&gt;If, for example the test of &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;table35&lt;/span&gt;&lt;/tt&gt; fails, we don't have to move back 35 characters, because we already know what those characters are, namely &lt;em&gt;the characters we matched to get to &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;table35&lt;/span&gt;&lt;/tt&gt;&lt;/em&gt;!
So the table in case of a failed match is always the same, and we can compute that as well.&lt;/p&gt;&lt;p&gt;Lets look again at the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;&lt;/tt&gt; function.
If &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; is the table we get for a failed match, we call &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt;&lt;/tt&gt; the &lt;em&gt;failure function&lt;/em&gt;, and pass it along as a second parameter.
For the first character, in case of a failed match we simply and start from the beginning for the next character:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Eq&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt;
   &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;' &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt;)&lt;/pre&gt;&lt;p&gt;
Notice we have &lt;em&gt;tied the knot&lt;/em&gt;, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt;&lt;/tt&gt; depends on &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;table&lt;/span&gt;&lt;/tt&gt; itself!
In Haskell this is not a problem because of lazy evaluation, as long as we don't try to &lt;em&gt;use&lt;/em&gt; what is not computed yet.&lt;/p&gt;&lt;p&gt;The &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;'&lt;/tt&gt; function is where the real work happens.
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;' &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;' &lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;KMP&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;test&lt;/span&gt;
   &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;test&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;success&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;
          &lt;span class=&quot;varid&quot;&gt;success&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;makeTable&lt;/span&gt;' &lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;))&lt;/pre&gt;&lt;p&gt;
The base case is not very interesting, although we can now use something better than &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;undefined&lt;/span&gt;&lt;/tt&gt;.
That becomes useful when looking for multiple matches.&lt;/p&gt;&lt;p&gt;The interesting clause is for &lt;tt&gt;&lt;span class=&quot;listcon&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;conop&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;)&lt;/span&gt;&lt;/tt&gt;. The &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt;&lt;/tt&gt; function compares a character &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;c&lt;/span&gt;&lt;/tt&gt; against &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt;.&lt;br&gt;
Is it the same? Great, move to the table for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;/tt&gt;.&lt;br&gt;
Is it different? Then look at the &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt;&lt;/tt&gt; function.&lt;/p&gt;&lt;p&gt;Finally, to determine the table for &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;xs&lt;/span&gt;&lt;/tt&gt;, we need a new failure function,
describing what would have happened if we started later and ended up at the position after &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;&lt;/tt&gt;.
We can ask the current failure function what would have happened in that case, &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;next&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt;)&lt;/tt&gt;.&lt;/p&gt;
&lt;h3&gt; Correctness &lt;/h3&gt;&lt;p&gt;It would be nice if we could be sure that what we have constructed is actually a substring matching algorithm.
The easiest way to verify that I use a simple QuickCheck property:
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;prop_isSubstringOf&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;listcon&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;listcon&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Bool&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;prop_isSubstringOf&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isSubstringOf`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;) &lt;span class=&quot;varop&quot;&gt;==&lt;/span&gt; (&lt;span class=&quot;varid&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;`isSubstringOf2`&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;bs&lt;/span&gt;)&lt;/pre&gt;&lt;pre class=&quot;nocode&quot;&gt;&gt; Test.QuickCheck.test prop_isSubstringOf
OK, passed 100 tests.&lt;/pre&gt;&lt;p&gt;
It seems to work, that's great.&lt;/p&gt;&lt;p&gt;An interesting exercise would be to prove that what I have made here is equivalent to the na&amp;iuml;ve algorithm
using equational reasoning.
Also nice would be comparing it to the imperative Knutt-Moris-Pratt algorithm, is this actually KMP?
Maybe next time.&lt;/p&gt;&lt;p&gt;&lt;b&gt;footnotes&lt;/b&gt;&lt;br&gt;
&lt;a name=&quot;infixof&quot;&gt;&amp;dagger;&lt;/a&gt; Actually, this function was recently added under the, in my opnion, wrong&lt;sup&gt;&amp;Dagger;&lt;/sup&gt; name &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;isInfixOf&lt;/span&gt;&lt;/tt&gt;.&lt;br&gt;
&lt;a name=&quot;infixof&quot;&gt;&amp;Dagger;&lt;/a&gt; It is wrong because while &quot;a is a prexif of b&quot; and &quot;a is a suffix of b&quot; are valid English sentences, there is as far as I know no such thing as &quot;an infix of&quot;. Maybe &quot;infix in&quot;, but not &quot;of&quot;. &amp;lt;/rant&gt;&lt;/p&gt;</description>
  </item>
  <item>
    <title>Formating system</title>
    <link>http://twan.home.fmf.nl/blog/test/test.details</link>
    <description>&lt;p&gt;
This is just a test post, to test my custom formating system.
It is written in Perl (because blosxom is). It is nothing more then a bunch of regular expressions, systematically bashing against a string.&lt;/p&gt;&lt;h3&gt; This will be a heading &lt;/h3&gt;&lt;p&gt;And this is a paragraph.&lt;/p&gt;&lt;p&gt;Break and start new.
&lt;/p&gt;&lt;ul&gt;&lt;li&gt; list&lt;/li&gt;
&lt;li&gt; list&lt;/li&gt;
&lt;li&gt; list&lt;/li&gt;
&lt;li&gt;# sublist&lt;/li&gt;
&lt;li&gt;# sublist&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;span class=&quot;pragmac&quot;&gt;&lt;span class=&quot;pragma&quot;&gt;{-# OPTIONS&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;_GHC&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;fglasgow&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;varid&quot;&gt;exts&lt;/span&gt; &lt;span class=&quot;pragma&quot;&gt;#-}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Code&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;conid&quot;&gt;Has&lt;/span&gt;&lt;span class=&quot;varop&quot;&gt;%%%&lt;/span&gt;&lt;span class=&quot;conid&quot;&gt;KEYWORDkell.Something&lt;/span&gt;

&lt;span class=&quot;varid&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;3&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt;  &lt;span class=&quot;varid&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;-- this is just a test&lt;/span&gt;
&lt;span class=&quot;varid&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;keyglyph&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;Something\n\&quot; asdf&quot;&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;nocode&quot;&gt;This is not a haskell module
if it is then else bla bla&lt;/pre&gt;&lt;p&gt;Something with &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt;&lt;/tt&gt;, &lt;span class=&quot;math&quot;&gt;inline math&lt;/span&gt;, &lt;em&gt;emphasis&lt;/em&gt;, &lt;strong&gt;strong emphasis&lt;/strong&gt;.
&lt;a href=&quot;something&quot;&gt;Links should work normally.&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Escaping: &lt;tt&gt;&lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt;&lt;/tt&gt;. But not &amp;amp;
&lt;/p&gt;&lt;pre&gt;&lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;varop&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;varid&quot;&gt;code&lt;/span&gt;&lt;/pre&gt;  &lt;ul&gt;
   &lt;li&gt;html goes here&lt;/li&gt;
  &lt;/ul&gt;</description>
  </item>
  </channel>
</rss>