<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Comonad.Reader &#187; Uncategorized</title>
	<atom:link href="http://comonad.com/reader/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://comonad.com/reader</link>
	<description>types, (co)monads, substructural logic</description>
	<lastBuildDate>Thu, 22 Jul 2010 19:53:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Pointed-Set Comonad</title>
		<link>http://comonad.com/reader/2008/the-pointed-set-comonad/</link>
		<comments>http://comonad.com/reader/2008/the-pointed-set-comonad/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 18:56:15 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Comonads]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/2008/the-pointed-set-comonad/</guid>
		<description><![CDATA[Last night, Chung-Chieh Shan posted an example of a pointed-set monad on his blog, which happens to be isomorphic to a non-empty stream monad with a different emphasis. 
But, I thought I should point out that the pointed set that he posted also has a comonadic structure, which may be exploited since it is just [...]]]></description>
			<content:encoded><![CDATA[<p>Last night, Chung-Chieh Shan posted an example of a <a href="http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Pointed_set/">pointed-set monad</a> on his blog, which happens to be isomorphic to a non-empty stream monad with a different emphasis. </p>
<p>But, I thought I should point out that the pointed set that he posted also has a comonadic structure, which may be exploited since it is just a variation on the "zipper comonad," a structure that is perhaps more correctly called a "pointing comonad."</p>
<p><span id="more-80"></span></p>
<p>But first, a little background:</p>
<p>With <a href="http://en.wikipedia.org/wiki/Combinatorial_species">combinatorial species</a> you point a data structure by marking a single element in it as special. We can represent that with the product of an element and the <a href="http://en.wikipedia.org/wiki/Derivative_(generalizations)#Set_theory_and_logic">derivative</a> of the original type.</p>
<pre>
F*[A] = A * F'[A]
</pre>
<p>So, then looking at Shan's pointed set, we can ask what combinatorial species has a list as its derivative? </p>
<p>The answer is a cycle, not a set. </p>
<p>This fact doesn't matter to the monad, since the only way a monadic action interacts with that extra structure is safely through bind, but does for the comonad where every comonadic action has access to that structure, but no control over the shape of the result.</p>
<p>However, we don't really have a way to represent an unordered set in Haskell, so if you are treating a list as a set, the derivative of a set is another set then we can also view the a * [a] as a pointed set, so long as we don't depend on the order of the elements in the list in any way in obtaining the result of our comonadic actions.</p>
<p>I've changed the name of his data type to <code>PointedSet</code> to avoid conflicting with the definitions of <code>Pointed</code> and <code>Copointed</code> functors in category extras.</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">module</span> PointedSet <span style="color: #06c; font-weight: bold;">where</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">import</span> Control.<a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#t:Comonad"><span style="background-color: #efefbf; font-weight: bold;">Comonad</span></a> <span style="color: #5d478b; font-style: italic;">-- from my category-extras library</span>
<span style="color: #06c; font-weight: bold;">import</span> Data.List <span style="color: green;">&#40;</span>inits,tails<span style="color: green;">&#41;</span> <span style="color: #5d478b; font-style: italic;">-- used much later below</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">data</span> PointedSet a = PointedSet a <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Eq"><span style="background-color: #efefbf; font-weight: bold;">Eq</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Ord"><span style="background-color: #efefbf; font-weight: bold;">Ord</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Show"><span style="background-color: #efefbf; font-weight: bold;">Show</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Read"><span style="background-color: #efefbf; font-weight: bold;">Read</span></a><span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> PointedSet <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>PointedSet x xs<span style="color: green;">&#41;</span> = PointedSet <span style="color: green;">&#40;</span>f x<span style="color: green;">&#41;</span> $ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f xs
&nbsp;</pre>
<p>The definition for extract is obvious, since you have already selected a point, just return it. </p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> Copointed PointedSet <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:extract"><span style="font-weight: bold;">extract</span></a> <span style="color: green;">&#40;</span>PointedSet x _<span style="color: green;">&#41;</span> = x
&nbsp;</pre>
<p>On the other hand, for duplicate we have a couple of options. An obvious and correct, but boring implementation transforms a value as follows:</p>
<pre class="haskell">&nbsp;
boring_duplicate :: PointedSet a -&gt; PointedSet <span style="color: green;">&#40;</span>PointedSet a<span style="color: green;">&#41;</span>
boring_duplicate xxs@<span style="color: green;">&#40;</span>PointedSet x xs<span style="color: green;">&#41;</span> =
    PointedSet xxs $ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip"><span style="font-weight: bold;">flip</span></a> PointedSet <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> xs
&nbsp;</pre>
<pre class="haskell">&nbsp;
*PointedSet&gt; boring_duplicate $ PointedSet <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>..<span style="color: red;">3</span><span style="color: green;">&#93;</span>
PointedSet <span style="color: green;">&#40;</span>PointedSet <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>..<span style="color: red;">3</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#91;</span>
    PointedSet <span style="color: red;">1</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>,
    PointedSet <span style="color: red;">2</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>,
    PointedSet <span style="color: red;">3</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
<span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>but that just abuses the fact that we can always return an empty list. </p>
<p>Another fairly boring interpretation is to just use the guts of the definition of the Stream comonad, but that doesn't model a set with a single memory singled out.</p>
<p>A more interesting version refocuses on each element of the list in turn, which makes the connection to the zipper comonad much more obvious. Since we want a pointed set and not a pointed cycle, we can focus on an element just by swapping out the element in the list in that position for the focus.</p>
<p>Again, since we can't specify general species in Haskell, this is as close as we can come to the correct comonadic structure for a pointed set. Due to the limitations of our type system, the comonadic action can still see the order of elements in the set, but it shouldn't use that information. </p>
<p>Since we don't care to preserve the order of the miscellaneous set elements, the <code>refocus</code> helper function below can just accumulate preceding elements in an accumulating parameter in reverse order.</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#t:Comonad"><span style="background-color: #efefbf; font-weight: bold;">Comonad</span></a> PointedSet <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> xxs@<span style="color: green;">&#40;</span>PointedSet x xs<span style="color: green;">&#41;</span> = PointedSet xxs $ refocus <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> x xs
      <span style="color: #06c; font-weight: bold;">where</span>
        refocus :: <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> -&gt; a -&gt; <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> -&gt; <span style="color: green;">&#91;</span>PointedSet a<span style="color: green;">&#93;</span>
        refocus acc x <span style="color: green;">&#40;</span>y:ys<span style="color: green;">&#41;</span> =
            PointedSet y <span style="color: green;">&#40;</span>acc ++ <span style="color: green;">&#40;</span>x:ys<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> : refocus <span style="color: green;">&#40;</span>y:acc<span style="color: green;">&#41;</span> x ys
        refocus acc x <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> = <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>Now,</p>
<pre class="haskell">&nbsp;
*PointedSet&gt; <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> $ PointedSet <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>..<span style="color: red;">3</span><span style="color: green;">&#93;</span> =
PointedSet <span style="color: green;">&#40;</span>PointedSet <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>,<span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#91;</span>
    PointedSet <span style="color: red;">1</span> <span style="color: green;">&#91;</span><span style="color: red;">0</span>,<span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span>,
    PointedSet <span style="color: red;">2</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>,<span style="color: red;">0</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span>,
    PointedSet <span style="color: red;">3</span> <span style="color: green;">&#91;</span><span style="color: red;">2</span>,<span style="color: red;">1</span>,<span style="color: red;">0</span><span style="color: green;">&#93;</span>
<span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>With that in hand we can define comonadic actions that can look at an entire <code>PointedSet</code> and return a value, then extend them comonadically to generate new pointed sets.</p>
<p>For instance, if we had a numerical pointed set and wanted to blur our focus somewhat we could weight an average between the focused and unfocused elements:</p>
<pre>
smooth :: Fractional a => a -> PointedSet a -> a
smooth w (PointedSet a as) =
    w * a +
    (1 - w) * sum as / fromIntegral (length as)
</pre>
<p>Smoothing is a safe pointed-set comonadic operation because it doesn't care about the order of the elements in the list.</p>
<p>And so now we can blur the distinction between the focused element and the rest of the set: </p>
<pre class="haskell">&nbsp;
*PointedSet&gt; <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:extend"><span style="font-weight: bold;">extend</span></a> <span style="color: green;">&#40;</span>smooth <span style="color: red;">0.5</span><span style="color: green;">&#41;</span> $ PointedSet <span style="color: red;">10</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>..<span style="color: red;">5</span><span style="color: green;">&#93;</span>
PointedSet <span style="color: red;">6.5</span> <span style="color: green;">&#91;</span><span style="color: red;">2.9</span>,<span style="color: red;">3.3</span>,<span style="color: red;">3.7</span>,<span style="color: red;">4.1</span>,<span style="color: red;">4.5</span><span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>A quick pass over the comonad laws shows that they all check out.</p>
<p>As noted above, if your comonadic action uses the order of the elements in the list beyond the selection of the focus, then it isn't really a valid pointed set comonadic operation. This is because we are abusing a list to approximate a (multi)set.</p>
<p><b>The Pointed-Cycle Comonad</b></p>
<p>A slight variation on this theme keeps the order of the elements the same in exchange for a more expensive refocusing operation and just rotates them through the focus. </p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">data</span> PointedCycle a = PointedCycle a <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Eq"><span style="background-color: #efefbf; font-weight: bold;">Eq</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Ord"><span style="background-color: #efefbf; font-weight: bold;">Ord</span></a>, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Show"><span style="background-color: #efefbf; font-weight: bold;">Show</span></a>,<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Read"><span style="background-color: #efefbf; font-weight: bold;">Read</span></a><span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> PointedCycle <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>PointedCycle x xs<span style="color: green;">&#41;</span> = PointedCycle <span style="color: green;">&#40;</span>f x<span style="color: green;">&#41;</span> $ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f xs
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> Copointed PointedCycle <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:extract"><span style="font-weight: bold;">extract</span></a> <span style="color: green;">&#40;</span>PointedCycle x _<span style="color: green;">&#41;</span> = x
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#t:Comonad"><span style="background-color: #efefbf; font-weight: bold;">Comonad</span></a> PointedCycle <span style="color: #06c; font-weight: bold;">where</span>
   <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> xxs@<span style="color: green;">&#40;</span>PointedCycle x xs<span style="color: green;">&#41;</span> =
        PointedCycle xxs . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> listToCycle . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:tail"><span style="font-weight: bold;">tail</span></a> $ rotations <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span>
     <span style="color: #06c; font-weight: bold;">where</span>
        rotations :: <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> -&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#93;</span>
        rotations xs = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:init"><span style="font-weight: bold;">init</span></a> $ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:zipWith"><span style="font-weight: bold;">zipWith</span></a> <span style="color: green;">&#40;</span>++<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>tails xs<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>inits xs<span style="color: green;">&#41;</span>
        listToCycle <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span> = PointedCycle x xs
&nbsp;</pre>
<p>With that you acknowledge that you really have a pointed cycle and the writer of the comonadic action can safely use the ordering information intrinsic to the list as a natural consequence of having taken the derivative of a cycle.</p>
<pre class="haskell">&nbsp;
*PointedSet&gt; <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> $ PointedCycle <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>..<span style="color: red;">3</span><span style="color: green;">&#93;</span>
PointedCycle <span style="color: green;">&#40;</span>PointedCycle <span style="color: red;">0</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span>,<span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#91;</span>
    PointedCycle <span style="color: red;">1</span> <span style="color: green;">&#91;</span><span style="color: red;">2</span>,<span style="color: red;">3</span>,<span style="color: red;">0</span><span style="color: green;">&#93;</span>,
    PointedCycle <span style="color: red;">2</span> <span style="color: green;">&#91;</span><span style="color: red;">3</span>,<span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#93;</span>,
    PointedCycle <span style="color: red;">3</span> <span style="color: green;">&#91;</span><span style="color: red;">0</span>,<span style="color: red;">1</span>,<span style="color: red;">2</span><span style="color: green;">&#93;</span>
<span style="color: green;">&#93;</span>
&nbsp;</pre>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2008/the-pointed-set-comonad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Still Alive</title>
		<link>http://comonad.com/reader/2008/still-alive/</link>
		<comments>http://comonad.com/reader/2008/still-alive/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 14:45:45 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/2008/still-alive/</guid>
		<description><![CDATA[To those that have asked, I'm still alive. 
I had to restore the blog database from a backup and so I lost a few posts, including the index for the various recursion schemes entries. Fortunately, before that happened I had replicated the catamorphism post as a knol.
Should I find myself with a copious glut of [...]]]></description>
			<content:encoded><![CDATA[<p>To those that have asked, I'm still alive. </p>
<p>I had to restore the blog database from a backup and so I lost a few posts, including the index for the various recursion schemes entries. Fortunately, before that happened I had replicated the <a href="http://knol.google.com/k/edward-kmett/catamorphisms/">catamorphism post as a knol</a>.</p>
<p>Should I find myself with a copious glut of free time, I shall happily re-scribe and finish the rest, but I've been very busy. </p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2008/still-alive/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Forgetful Laziness</title>
		<link>http://comonad.com/reader/2008/forgetful-laziness/</link>
		<comments>http://comonad.com/reader/2008/forgetful-laziness/#comments</comments>
		<pubDate>Fri, 16 May 2008 22:25:06 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/2008/forgetful-laziness/</guid>
		<description><![CDATA[Does anyone know of any work on "forgetful laziness?"

The basic idea being that for each thunk instead of overwriting it with the answer as usual in call-by-need, you'd just write a forwarding pointer, and allow GC to collect the answers over time. 
This results in recalculation and may be subject to thrashing, so the obvious [...]]]></description>
			<content:encoded><![CDATA[<p>Does anyone know of any work on "forgetful laziness?"</p>
<p><span id="more-59"></span></p>
<p>The basic idea being that for each thunk instead of overwriting it with the answer as usual in call-by-need, you'd just write a forwarding pointer, and allow GC to collect the answers over time. </p>
<p>This results in recalculation and may be subject to thrashing, so the obvious fix would be either</p>
<ol>
<li> a 'forget at most once' policy, which would only mitigate the kind of memory leaks you get from laziness under limited conditions, but which has a worst case payout of doubling the workload or
</li>
<li> an exponential backoff on how often you'll try to recollect a given value, which should preserve for practical purposes the asymptotic behavior of any algorithm, but with a much larger constant for pathological access patterns. [Edit: it may affect asymptotic behavior, because you could lose sharing]
</li>
</ol>
<p>This would allow the recollection of large CAFs, etc. eventually once they had bitrotted long enough. </p>
<p>Not sure if its worth the cost of recalculating and of storing any backoff counter, but most of the horror stories you hear about Haskell center around its occasional horrific memory usage profile.</p>
<p>Tuning points might include studying average thunk lifetimes to construct thunk access profiles rather than use a naive exponential backoff.</p>
<p>It also may exascerbate the opposite problem where naive code often builds up a tower of thunks it needs to evaluate all at once in order to provide an answer (i.e. when working with a lazy accumulating parameter).</p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2008/forgetful-laziness/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Unnatural Transformations</title>
		<link>http://comonad.com/reader/2008/unnatural-transformations/</link>
		<comments>http://comonad.com/reader/2008/unnatural-transformations/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 00:43:08 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Category Theory]]></category>
		<category><![CDATA[Comonads]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Monads]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/2008/unnatural-transformations/</guid>
		<description><![CDATA[Back in the days of HYLO, it was common to write hylomorphisms with an additional natural transformation in them. Well, I was still coding in evil imperative languages back then, but I have it on reliable, er.. well supposition, that this is probably the case, or at least that they liked to do it back [...]]]></description>
			<content:encoded><![CDATA[<p>Back in the days of <a href="http://citeseer.ist.psu.edu/41091.html">HYLO</a>, it was common to write hylomorphisms with an additional natural transformation in them. Well, I was still coding in evil imperative languages back then, but I have it on reliable, er.. well supposition, that this is probably the case, or at least that they liked to do it back in the HYLO papers anyways.</p>
<p>Transcoding the category theory mumbo-jumbo into Haskell, so I can have a larger audience, we get the following 'frat combinator' -- you can blame Jules Bean from #haskell for that.</p>
<pre class="haskell">&nbsp;
hyloEta :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f =&gt;
     <span style="color: green;">&#40;</span>g b -&gt; b<span style="color: green;">&#41;</span> -&gt;
     <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> a. f a -&gt; g a<span style="color: green;">&#41;</span> -&gt;
     <span style="color: green;">&#40;</span>a -&gt; f a<span style="color: green;">&#41;</span>
hyloEta phi eta psi = phi . eta . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>hyloEta phi eta psi<span style="color: green;">&#41;</span> . psi
&nbsp;</pre>
<p>We placed eta in the middle of the argument list because it is evocative of the fact that it occurs between phi and psi, and because that seems to be where everyone else puts it. </p>
<p>Now, clearly, we could roll eta into phi and get the more traditional hylo where f = g. Less obviously we could roll it into psi because it is a <a href="http://en.wikipedia.org/wiki/Natural_transformation">natural transformation</a> and so the following diagram commutes:</p>
<div class="codeblock" align="center">
<img src='http://comonad.com/latex/eb518f091c90f6025d7669a9291b6c29.png' title='\bfig \square/&gt;`&gt;`&gt;`&gt;/[F(A)`F(B)`G(A)`G(B);F {[}\hspace{-0.8pt}{[}f, g{]}\hspace{-0.8pt}{]} `\eta_A`\eta_B`G {[}\hspace{-0.8pt}{[}f, g{]}\hspace{-0.8pt}{]}] \efig ' alt='\bfig \square/&gt;`&gt;`&gt;`&gt;/[F(A)`F(B)`G(A)`G(B);F {[}\hspace{-0.8pt}{[}f, g{]}\hspace{-0.8pt}{]} `\eta_A`\eta_B`G {[}\hspace{-0.8pt}{[}f, g{]}\hspace{-0.8pt}{]}] \efig ' align=absmiddle>
</div>
<p>This 'Hylo Shift' property (mentioned in that same paper) allows us to move the 'eta' term into the phi term or into the psi term as we see fit. Since we can move the eta term around and it adds no value to the combinator, it quietly returned to the void from whence it came. hyloEta offers us no more power than hylo, so out it goes.</p>
<p>So, if its dead, why talk about it?</p>
<p><span id="more-50"></span></p>
<p>Well, when we move to a generalized hylomorphism we have a design decision that has some performance effects, and my initial pass at a generalized hylomorphism isn't as general as it could be. When we open up the generalized hylomorphism and look at its guts (check the slightly updated <a href="http://comonad.com/haskell/Chronomorphism.hs">source code</a> from yesterday) we see:</p>
<pre class="haskell">&nbsp;
g_hylo' w m f g = liftW f . w . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g_hylo' w m f g<span style="color: green;">&#41;</span> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> join . m . liftM g
&nbsp;</pre>
<p>expanding that to include the eta term gives us 4 candidate locations where we can abuse its status as a natural transformation to slot it in.</p>
<pre class="haskell">&nbsp;
g_hylo'<span style="color: red;">1</span> w m f eta g =
    liftW f .
    w . eta . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g_hylo' w m f g<span style="color: green;">&#41;</span> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> join . m .
    liftM g
g_hylo'<span style="color: red;">2</span> w m f eta g =
    liftW f .
    w . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> . eta . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g_hylo' w m f g<span style="color: green;">&#41;</span> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> join . m .
    liftM g
g_hylo'<span style="color: red;">3</span> w m f eta g =
    liftW f .
    w . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g_hylo' w m f g<span style="color: green;">&#41;</span> . eta . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> join . m .
    liftM g
g_hylo'<span style="color: red;">4</span> w m f eta g =
    liftW f .
    w . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://comonad.com/haskell/category-extras/dist/doc/html/category-extras/Control-Comonad.html#v:duplicate"><span style="font-weight: bold;">duplicate</span></a> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g_hylo' w m f g<span style="color: green;">&#41;</span> . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> join . eta . m .
    liftM g
&nbsp;</pre>
<p>g-hylo'1 and g_hylo'4 are particularly interesting because we have functions sitting right next to them that we can fuse it into by generalizing the type signatures only slightly and because that leaves a run of 3 fmaps in a row that we can fuse together. If we generalize the signatures of both w and m we get the following definition that allows you to place it on the left or the right, and for g_hylo to not have to care about it. </p>
<pre language="haskell">
-- new and improved!
g_hylo :: (Comonad w, Functor f, Monad m) =>
          (forall a. f (w a) -> w (g a)) ->
          (forall a. m (e a) -> f (m a)) ->
          (g (w b) -> b) ->
          (a -> e (m a)) ->
          (a -> b)
g_hylo w m f g = extract . g_hylo' w m f g . return

-- | the kernel of the generalized hylomorphism
g_hylo' :: (Comonad w, Functor f, Monad m) =>
           (forall a. f (w a) -> w (g a)) ->
           (forall a. m (e a) -> f (m a)) ->
           (g (w b) -> b) ->
           (a -> e (m a)) ->
           (m a -> w b)
g_hylo' w m f g = liftW f . w . fmap (duplicate . g_hylo' w m f g . join) . m . liftM g
</pre>
<p>The slightly generalized signatures for our two distributive laws now allow them to change functors on the way through, but we shed a superfluous argument.</p>
<p>Note that while 3 'Functors' e, f and g are involved, only f needs to be a Functor in Hask because we do the duplication, hylomorphism and join all inside f in either case. And most of the time e = f = g. For instance e or g could be <a href="http://comonad.com/reader/2008/rotten-bananas/">exponential</a> or <a href="http://mathworld.wolfram.com/ContravariantFunctor.html">contravariant</a>. </p>
<p>So now that we've generalized our generalized hylomorphism we're done right?</p>
<p>Not quite. Unfortunately the same trick doesn't work for the <a href="http://comonad.com/reader/2008/time-for-chronomorphisms/">generalized chronomorphism</a> defined last night. </p>
<p>To see why, we have open up chrono and peek at its guts.</p>
<pre class="haskell">&nbsp;
chrono = g_chrono <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
&nbsp;</pre>
<p>Well, that was boring. Digging deeper we find:</p>
<pre class="haskell">&nbsp;
g_chrono :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> g, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> m, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> w<span style="color: green;">&#41;</span> =&gt;
            <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> b. f <span style="color: green;">&#40;</span>w b<span style="color: green;">&#41;</span> -&gt; w <span style="color: green;">&#40;</span>f b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> b. m <span style="color: green;">&#40;</span>f b<span style="color: green;">&#41;</span> -&gt; f <span style="color: green;">&#40;</span>m b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span>Cofree w b<span style="color: green;">&#41;</span> -&gt; b<span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span>a -&gt; f <span style="color: green;">&#40;</span>Free m a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            a -&gt; b
g_chrono w m = g_hylo <span style="color: green;">&#40;</span>distCofree w<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>distFree m<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>Sticking in hylo's vestigial natural transformation, we get:</p>
<pre class="haskell">&nbsp;
g_chronoEta :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> g, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> m, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> w<span style="color: green;">&#41;</span> =&gt;
            <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> b. g <span style="color: green;">&#40;</span>w b<span style="color: green;">&#41;</span> -&gt; w <span style="color: green;">&#40;</span>g b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> b. m <span style="color: green;">&#40;</span>f b<span style="color: green;">&#41;</span> -&gt; f <span style="color: green;">&#40;</span>m b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span>Cofree w b<span style="color: green;">&#41;</span> -&gt; b<span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> c. f a -&gt; g a<span style="color: green;">&#41;</span> -&gt;
            <span style="color: green;">&#40;</span>a -&gt; f <span style="color: green;">&#40;</span>Free m a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
            a -&gt; b
g_chronoEta w m f eta g = g_hylo <span style="color: green;">&#40;</span>distCofree w . eta<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>distFree m<span style="color: green;">&#41;</span> f g
<span style="color: #5d478b; font-style: italic;">-- g_chronoEta w m f eta g = g_hylo (distCofree w) (eta . distFree m) f g</span>
&nbsp;</pre>
<p>And so, we roll up our sleeves ready to merge it into something, be it f, g, w, m, anything, but it seems the only places eta can go is to merge into one of the distributive laws, because f and g are executed lifted.</p>
<p>Unfortunately, the user passed us rules for distributing the base functor of the cofree comonad and free monad, not for distributing the whole cofree comonad. And my efforts to generalize distFree and distCofree have thus far met with some frustration, there isn't much to grab onto there to write the more general signature.</p>
<p>Ideally, I'd just be able to merge it into one of the distributive laws. Since the HYLO guys liked to put it on the left of the recursive call to the hylomorphism, we'll look at distCofree. The desired signature for distCofree' would be:</p>
<pre class="haskell">&nbsp;
distCofree' ::   <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> g, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> h<span style="color: green;">&#41;</span> =&gt;
                <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">forall</span> a. f <span style="color: green;">&#40;</span>h a<span style="color: green;">&#41;</span> -&gt; h <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
                f <span style="color: green;">&#40;</span>Cofree h a<span style="color: green;">&#41;</span> -&gt; Cofree h <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>and it should have the property that:</p>
<pre class="haskell">&nbsp;
distCofree' <span style="color: green;">&#40;</span>f . eta<span style="color: green;">&#41;</span> == distCofree' f . eta
&nbsp;</pre>
<p>Without that, g_chronoEta is more powerful than g_chrono. Naturally.</p>
<p><a href="http://comonad.com/haskell/Chronomorphism.hs">Source Code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2008/unnatural-transformations/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Elgot Algebras</title>
		<link>http://comonad.com/reader/2008/elgot-algebras/</link>
		<comments>http://comonad.com/reader/2008/elgot-algebras/#comments</comments>
		<pubDate>Tue, 01 Jan 2008 17:05:14 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/1970/elgot-algebras/</guid>
		<description><![CDATA[Wordpress changed the slug of this post, but Planet Haskell has the old link.
Here is the actual content.
]]></description>
			<content:encoded><![CDATA[<p>Wordpress changed the slug of this post, but Planet Haskell has the old link.</p>
<p><a href="http://comonad.com/reader/2008/elgot-coalgebras">Here is the actual content</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2008/elgot-algebras/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated Data.Type.*</title>
		<link>http://comonad.com/reader/2007/updated-datatype/</link>
		<comments>http://comonad.com/reader/2007/updated-datatype/#comments</comments>
		<pubDate>Sat, 14 Jul 2007 02:57:14 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Type Hackery]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/2007/updated-datatype/</guid>
		<description><![CDATA[Updated my little type-level 2s and 16s complement integer library to be ghc 6.6 friendly and uploaded it to hackage based on popular (er.. ok, well, singular) demand. 
O.K. it was more of a polite request, but I did update it.
]]></description>
			<content:encoded><![CDATA[<p>Updated my little <a href="http://comonad.com/haskell/type-int/">type-level 2s and 16s complement integer library</a> to be ghc 6.6 friendly and uploaded it to <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/type-int-0.4">hackage</a> based on popular (er.. ok, well, singular) demand. </p>
<p>O.K. it was more of a polite request, but I did update it.</p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2007/updated-datatype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
