<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6839213</id><updated>2011-04-21T22:36:50.841-04:00</updated><category term='haskell'/><title type='text'>The Bad Rabbit</title><subtitle type='html'>Bad Rabbit.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://banbh.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6839213.post-4887975598806123066</id><published>2007-08-27T22:56:00.000-04:00</published><updated>2007-08-27T22:57:01.231-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>Pascal's Triangle</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Pascal's_triangle"&gt;Pascal's triangle&lt;/a&gt;
can be defined directly 

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='varid'&gt;n&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='varid'&gt;n&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;m&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
This direct implementation is very inefficient, much as
the direct computation of the
&lt;a href="http://en.wikipedia.org/wiki/Fibonacci_sequence"&gt;Fibonacci
sequence&lt;/a&gt;

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='varid'&gt;n&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
is inefficient.  An elegant way to compute this sequence exploits
sharing and laziness.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fibs&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='conop'&gt;:&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt; &lt;span class='conop'&gt;:&lt;/span&gt; &lt;span class='varid'&gt;zipWith&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;fibs&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;tail&lt;/span&gt; &lt;span class='varid'&gt;fibs&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
So, for example, &lt;code&gt;fib 6 == fibs!!6&lt;/code&gt;.
(You can see 
&lt;a href="http://www.haskell.org/haskellwiki/The_Fibonacci_sequence#Canonical_zipWith_implementation"&gt;the 
above defintion and others&lt;/a&gt; on the Haskell 
wiki.)

A nice exercise is to pull the same stunt with Pascal's triangle.
Instead of a list we need a tree and some obvious operations on it.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;data&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;value&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;value&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;zipTreeWith&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;zipTreeWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;x1&lt;/span&gt; &lt;span class='varid'&gt;l1&lt;/span&gt; &lt;span class='varid'&gt;r1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;x2&lt;/span&gt; &lt;span class='varid'&gt;l2&lt;/span&gt; &lt;span class='varid'&gt;r2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;      &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;x1&lt;/span&gt; &lt;span class='varid'&gt;x2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;zipTreeWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;l1&lt;/span&gt; &lt;span class='varid'&gt;l2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;zipTreeWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;r1&lt;/span&gt; &lt;span class='varid'&gt;r2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
We can now define a generic (replacing addition with an arbitrary operation
&lt;code&gt;op&lt;/code&gt;) Pascal's triangle.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascals'&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascals'&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;   &lt;span class='keyword'&gt;where&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;zipTreeWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;         &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;leftone&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;         &lt;span class='varid'&gt;r&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;rightone&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;         &lt;span class='varid'&gt;leftone&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;leftone&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;         &lt;span class='varid'&gt;rightone&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;rightone&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='varid'&gt;t&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
(The above version is due to JS and I prefer it to the version I came 
up with.)  We get what we want by specialising.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascals&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;T&lt;/span&gt; &lt;span class='conid'&gt;Integer&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascals&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;pascals'&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
We make it easy to get values out of the tree with this helper:

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;pascalsHelper&lt;/span&gt; &lt;span class='varid'&gt;n&lt;/span&gt; &lt;span class='varid'&gt;m&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;value&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;iterate&lt;/span&gt; &lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;iterate&lt;/span&gt; &lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='varid'&gt;pascals&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='varid'&gt;m&lt;/span&gt;
&lt;/pre&gt;
Finally we can test it.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;main&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;print&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='varid'&gt;and&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;pascalsHelper&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varid'&gt;y&lt;/span&gt; &lt;span class='varop'&gt;==&lt;/span&gt; &lt;span class='varid'&gt;pascal1&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varid'&gt;y&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='keyglyph'&gt;..&lt;/span&gt;&lt;span class='num'&gt;5&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;y&lt;/span&gt; &lt;span class='keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='keyglyph'&gt;..&lt;/span&gt;&lt;span class='num'&gt;5&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6839213-4887975598806123066?l=banbh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/4887975598806123066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6839213&amp;postID=4887975598806123066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/4887975598806123066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/4887975598806123066'/><link rel='alternate' type='text/html' href='http://banbh.blogspot.com/2007/08/pascals-triangle.html' title='Pascal&apos;s Triangle'/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6839213.post-7719756532303619250</id><published>2007-08-26T20:12:00.000-04:00</published><updated>2007-08-26T21:06:25.794-04:00</updated><title type='text'>Formatting Haskell</title><content type='html'>I've been experimenting with formatting Haskell for this
blog and thought I would summarize my conclusions.
&lt;/p&gt;&lt;p&gt;
My needs are unsurprising: I want to write literate Haskell (LHS),
have it look nice on the blog, and have the process be easy (in
other words, mostly automated).
&lt;/p&gt;&lt;p&gt;
One possibility is to take the LHS, wrap it in &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;
tags and post it.  This works, but I was curious to try
&lt;a href="http://www.cs.york.ac.uk/fp/darcs/hscolour"&gt;hscolour&lt;/a&gt;.
The current version (I got mine directly from darcs) supports
LHS.  A nice feature of hscolour is that it can output HTML with the
formatting in the form CSS classes.  Thus, I could factor out 
the appearance of my Haskell code into the embedded
stylesheet of my blog template.
&lt;/p&gt;&lt;p&gt;
This left me with just one minor quibble.  I wanted to hide the "&amp;gt; "
with which every line of code in LHS starts.  Unfortunately the current
implementation of hscolor treats these as a regular Haskell token, so
they get styled like any other operator.  So after a little hacking of
the hscolour source, I had a new hscolour that did exactly what I wanted.
&lt;/p&gt;&lt;p&gt;
The color scheme is nothing to write home about, but while tinkering with
it I did discover a small quirk of how browsers interpret CSS (it might 
not even be a quirk -- I should read the W3C spec).  
I wanted to style "&amp;gt; " with &lt;code&gt;display:none&lt;/code&gt;.  However
with that property, if you cut and paste the post, you lose the
"&amp;gt; "s.  So instead I just made them the same color as the backgound.
&lt;/p&gt;&lt;p&gt;
Finally I used an &lt;a href="http://omake.metaprl.org"&gt;OMake&lt;/a&gt; script
to automate compiling the code and converting it into HTML.
&lt;/p&gt;&lt;p&gt;
If I had a great deal of spare time, the following would be nice.
&lt;ul&gt;
&lt;li&gt;Integrate &lt;a href="http://sophos.berkeley.edu/macfarlane/pandoc"&gt;Pandoc&lt;/a&gt;
into the process so my LHS can look more like text and yet be mechanically 
converted to pleasant HTML.&lt;/li&gt;
&lt;li&gt;Automate the upload process using the blog's XML API.  Others 
&lt;a href="http://www.serpentine.com/blog/2007/01/30/blogging-with-emacs-and-haskell-part-zero/"&gt;have 
already done something similar&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6839213-7719756532303619250?l=banbh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/7719756532303619250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6839213&amp;postID=7719756532303619250' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/7719756532303619250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/7719756532303619250'/><link rel='alternate' type='text/html' href='http://banbh.blogspot.com/2007/08/formatting-haskell.html' title='Formatting Haskell'/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6839213.post-6233028480576492234</id><published>2007-08-25T21:30:00.000-04:00</published><updated>2007-08-26T19:09:34.448-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'>Relative Spreadsheets</title><content type='html'>A post of sigfpe discusses &lt;a href="http://sigfpe.blogspot.com/2006/11/from-l-theorem-to-spreadsheet.html"&gt;spreadheets&lt;/a&gt; (and much more).  He defines a beautiful function &lt;code&gt;loeb&lt;/code&gt;:

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;loeb&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Functor&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;loeb&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;fmap&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='keyglyph'&gt;\&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;loeb&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;/pre&gt;
which allows one to define something similar to a (one dimensional)
spreadsheet

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;spreadsheet1&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;length&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt;&lt;span class='keyglyph'&gt;\&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='num'&gt;0&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/pre&gt;
so &lt;code&gt;loeb spreadsheet1&lt;/code&gt; is &lt;code&gt;[2,2]&lt;/code&gt;.  It can be made more compelling with help of some sugar that makes functions into things we can add and subtract:

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='conid'&gt;Show&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='conid'&gt;Eq&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;Num&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt;&lt;span class='conid'&gt;Eq&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Num&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;fromInteger&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;const&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;fromInteger&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;g&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;\&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;g&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varop'&gt;*&lt;/span&gt; &lt;span class='varid'&gt;g&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;\&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varop'&gt;*&lt;/span&gt; &lt;span class='varid'&gt;g&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;negate&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;negate&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;abs&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;abs&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;    &lt;span class='varid'&gt;signum&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;signum&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
then we can define a more interesting spreadsheet:

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;spreadsheet2&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='num'&gt;5&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='num'&gt;3&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='num'&gt;0&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='varop'&gt;+&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;!!&lt;/span&gt;&lt;span class='num'&gt;2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='varop'&gt;*&lt;/span&gt;&lt;span class='num'&gt;2&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;sum&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;take&lt;/span&gt; &lt;span class='num'&gt;3&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='num'&gt;17&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/pre&gt;
and &lt;code&gt;loeb spreadsheet2&lt;/code&gt; is &lt;code&gt;[17,3,20,40,40,17]&lt;/code&gt;.

However the functions living in each cell are &lt;em&gt;absolute&lt;/em&gt;.  If it
were Excel, they would have dollar signs in them.  Normal functions in a
spreadsheet are best consider to be using &lt;em&gt;relative&lt;/em&gt; addressing
(this observation is due to JS).  At this point you should read
the second inspiration for this post, again by sigfpe where he discusses &lt;a href="http://sigfpe.blogspot.com/2006/12/evaluating-cellular-automata-is.html"&gt;comonads and zippers&lt;/a&gt;.

Repeating his definitions here, we make &lt;code&gt;U&lt;/code&gt; into the zipper
derived from a list and define functions to walk left and right along
the list.  We also make it into a functor.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;data&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;cs&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;b&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt; &lt;span class='varid'&gt;cs&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;left&lt;/span&gt;  &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='keyword'&gt;as&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='keyword'&gt;as&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;b&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='conid'&gt;Functor&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;   &lt;span class='varid'&gt;fmap&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;map&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;map&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
It turns out that &lt;code&gt;U&lt;/code&gt; is a comonad, but all we'll
ignore that and simply define the following two oddly-named
functions.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;cojoin&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;tail&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='varid'&gt;iterate&lt;/span&gt; &lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;tail&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='varid'&gt;iterate&lt;/span&gt; &lt;span class='varid'&gt;right&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;coreturn&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt;
&lt;/pre&gt;
Next we define a function to walk an integer number of steps
along the zipper and a one to access the nth element.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;shift&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;u&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;iterate&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='keyword'&gt;if&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt;&lt;span class='varop'&gt;&amp;lt;&lt;/span&gt;&lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='keyword'&gt;then&lt;/span&gt; &lt;span class='varid'&gt;left&lt;/span&gt; &lt;span class='keyword'&gt;else&lt;/span&gt; &lt;span class='varid'&gt;right&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;u&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;!!&lt;/span&gt; &lt;span class='varid'&gt;abs&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;at&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;u&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;coreturn&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;shift&lt;/span&gt; &lt;span class='varid'&gt;i&lt;/span&gt; &lt;span class='varid'&gt;u&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
Armed with all this we can define a new &lt;code&gt;loeb&lt;/code&gt; function,
similar to sigfpe's except that it works in a relative way (which is
interesting) but is much less general, since it only works with
&lt;code&gt;U&lt;/code&gt;.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;uzipWith&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;c&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;uzipWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;laa&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;raa&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;lbb&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt; &lt;span class='varid'&gt;rbb&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;zipWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;laa&lt;/span&gt; &lt;span class='varid'&gt;lbb&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varid'&gt;b&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;zipWith&lt;/span&gt; &lt;span class='varid'&gt;op&lt;/span&gt; &lt;span class='varid'&gt;raa&lt;/span&gt; &lt;span class='varid'&gt;rbb&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;uloeb&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;uloeb&lt;/span&gt; &lt;span class='varid'&gt;ff&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;uzipWith&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;ff&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;cojoin&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;uloeb&lt;/span&gt; &lt;span class='varid'&gt;ff&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
Finally we can define our Fibonacci spreadsheet.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fibSpreadsheet&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;repeat&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;repeat&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;at&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;at&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
(At this point it's hard not to think of &lt;a href="http://www.willamette.edu/~fruehr/haskell/evolution.html"&gt;The Evolution of a Haskell Programmer&lt;/a&gt;.)  Now to test it, we define
an obviously correct (and inefficient) computation of the Fibonacci
sequence.

&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='num'&gt;1&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='varid'&gt;n&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;+&lt;/span&gt; &lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;n&lt;/span&gt;&lt;span class='comment'&gt;-&lt;/span&gt;&lt;span class='num'&gt;2&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;pre&gt;&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;&lt;span class='varid'&gt;main&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyword'&gt;do&lt;/span&gt; &lt;span class='keyword'&gt;let&lt;/span&gt; &lt;span class='conid'&gt;U&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='varid'&gt;rr&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;uloeb&lt;/span&gt; &lt;span class='varid'&gt;fibSpreadsheet&lt;/span&gt;
&lt;span class='lhs'&gt;&amp;gt; &lt;/span&gt;          &lt;span class='varid'&gt;print&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='varid'&gt;map&lt;/span&gt; &lt;span class='varid'&gt;fib&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='num'&gt;1&lt;/span&gt;&lt;span class='keyglyph'&gt;..&lt;/span&gt;&lt;span class='num'&gt;10&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt; &lt;span class='varop'&gt;==&lt;/span&gt; &lt;span class='varid'&gt;take&lt;/span&gt; &lt;span class='num'&gt;10&lt;/span&gt; &lt;span class='varid'&gt;rr&lt;/span&gt;
&lt;/pre&gt;
Two parting comments:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;uloeb fibSpreadsheet&lt;/code&gt; is, in fact, efficient.&lt;/li&gt;
&lt;li&gt;The definition of &lt;code&gt;cojoin&lt;/code&gt; could have used &lt;code&gt;repeat&lt;/code&gt; instead
of &lt;code&gt;iterate left&lt;/code&gt; and &lt;code&gt;iterate right&lt;/code&gt;, in which case 
&lt;code&gt;uloeb&lt;/code&gt; would have ended up being an absolute version of this one,
i.e., it would have similar to sigfpe's &lt;code&gt;loeb&lt;/code&gt; except not as general.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uloeb&lt;/code&gt; is not as general as I might have hoped.  It would be nice if
it worked with any functor, or perhaps comonad.  Perhaps there is some other type class
lurking here.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6839213-6233028480576492234?l=banbh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/6233028480576492234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6839213&amp;postID=6233028480576492234' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/6233028480576492234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/6233028480576492234'/><link rel='alternate' type='text/html' href='http://banbh.blogspot.com/2007/08/relative-spreadsheets.html' title='Relative Spreadsheets'/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6839213.post-5842045770028324677</id><published>2007-08-13T20:26:00.000-04:00</published><updated>2007-08-13T20:40:28.737-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><title type='text'></title><content type='html'>Are partial functions null in sheep's clothing?  For example

&gt; length [1,2,undefined]

is 3, but what is the third (!!2) element?  Kind of like inserting null into a list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6839213-5842045770028324677?l=banbh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/5842045770028324677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6839213&amp;postID=5842045770028324677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/5842045770028324677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/5842045770028324677'/><link rel='alternate' type='text/html' href='http://banbh.blogspot.com/2007/08/are-partial-functions-null-in-sheeps.html' title=''/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6839213.post-108293399412032467</id><published>2004-04-25T18:59:00.000-04:00</published><updated>2007-08-26T12:47:35.285-04:00</updated><title type='text'>The Inevitable First Post</title><content type='html'>My first post.&lt;blockquote&gt;A &lt;b&gt;block&lt;/b&gt; quote
with two lines&lt;/blockquote&gt;Also, here is some code with a &lt;code&gt;printf&lt;/code&gt;
&lt;pre&gt;
void main() {
  printf("hello");
}
&lt;/pre&gt;
So there.
This should not be on a new line.

Nor should this.&lt;br/&gt;
This should be on a new line.&lt;br/&gt;
&lt;br/&gt;
And this should be &lt;b&gt;two&lt;/b&gt; lines down.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6839213-108293399412032467?l=banbh.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://cnn.com' title='The Inevitable First Post'/><link rel='replies' type='application/atom+xml' href='http://banbh.blogspot.com/feeds/108293399412032467/comments/default' title='Post Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/108293399412032467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6839213/posts/default/108293399412032467'/><author><name>banbh</name><uri>http://www.blogger.com/profile/06470779597822858037</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
