<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
	<title>Comments for Conal Elliott</title>
	
	<link>http://conal.net/blog</link>
	<description>Inspirations &amp; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Sun, 06 May 2012 23:12:04 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
	<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/conal-comments" /><feedburner:info uri="conal-comments" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Comment on Elegant memoization with functional memo tries by conal</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/VsbgDWIiXZQ/comment-page-1</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Sun, 06 May 2012 23:12:04 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=54#comment-109124</guid>
		<description>&lt;p&gt;Hi Audun. I like your idea of a &lt;code&gt;HasTrie Void&lt;/code&gt; instance. Omitting it was an oversight. I just added your instance and released &lt;a href="http://hackage.haskell.org/package/MemoTrie-0.4.12" rel="nofollow"&gt;version 0.4.12&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think you meant "there is one function &lt;code&gt;Void -&gt; a&lt;/code&gt;" (rather than none), ignoring bottoms, namely the empty function.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Audun. I like your idea of a <code>HasTrie Void</code> instance. Omitting it was an oversight. I just added your instance and released <a href="http://hackage.haskell.org/package/MemoTrie-0.4.12" rel="nofollow">version 0.4.12</a>.</p>

<p>I think you meant &#8220;there is one function <code>Void -&gt; a</code>&#8221; (rather than none), ignoring bottoms, namely the empty function.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/comment-page-1#comment-109124</feedburner:origLink></item>
	<item>
		<title>Comment on Elegant memoization with functional memo tries by Audun</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/ptyZl7RN06M/comment-page-1</link>
		<dc:creator>Audun</dc:creator>
		<pubDate>Sat, 21 Apr 2012 19:26:45 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=54#comment-107190</guid>
		<description>&lt;p&gt;Hi,
I had use for a HasTrie instance for the Void type. I could think of two instances. The instance that would seem to follow from the isomorphisms is:&lt;/p&gt;

&lt;p&gt;instance HasTrie Void where
  data Void :-&gt;: a = VoidTrie
  trie _ = VoidTrie
  untrie VoidTrie = absurd
  enumerate VoidTrie = []&lt;/p&gt;

&lt;p&gt;That is, there are no functions Void -&gt; a, and a^Void is isomorphic to Unit. However, this instance makes constant functions strict, so that
memo (const a) undefined == undefined.
This can be alleviated with an instance closer to the Unit instance.&lt;/p&gt;

&lt;p&gt;Any thoughts? Would you be willing to add a Void instance to MemoTrie?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi,
I had use for a HasTrie instance for the Void type. I could think of two instances. The instance that would seem to follow from the isomorphisms is:</p>

<p>instance HasTrie Void where
  data Void :-&gt;: a = VoidTrie
  trie _ = VoidTrie
  untrie VoidTrie = absurd
  enumerate VoidTrie = []</p>

<p>That is, there are no functions Void -&gt; a, and a^Void is isomorphic to Unit. However, this instance makes constant functions strict, so that
memo (const a) undefined == undefined.
This can be alleviated with an instance closer to the Unit instance.</p>

<p>Any thoughts? Would you be willing to add a Void instance to MemoTrie?</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/comment-page-1#comment-107190</feedburner:origLink></item>
	<item>
		<title>Comment on Garbage collecting the semantics of FRP by Sjoerd Visscher</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/aUtlJK6nIIc/comment-page-1</link>
		<dc:creator>Sjoerd Visscher</dc:creator>
		<pubDate>Mon, 21 Nov 2011 12:42:05 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=96#comment-90982</guid>
		<description>&lt;p&gt;You might be interested in this: http://www.reddit.com/r/haskell/comments/mj23v/new_video_lecture_how_to_be_more_productive/&lt;/p&gt;

&lt;p&gt;I wonder if it is possible (or makes sense even) to apply the Banach fixed-point theorem to the continuous time model.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>You might be interested in this: <a href="http://www.reddit.com/r/haskell/comments/mj23v/new_video_lecture_how_to_be_more_productive/" rel="nofollow">http://www.reddit.com/r/haskell/comments/mj23v/new_video_lecture_how_to_be_more_productive/</a></p>

<p>I wonder if it is possible (or makes sense even) to apply the Banach fixed-point theorem to the continuous time model.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/garbage-collecting-the-semantics-of-frp/comment-page-1#comment-90982</feedburner:origLink></item>
	<item>
		<title>Comment on Is Haskell a purely functional language? by Andy Melnikov</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/8ZnO4mL13lI/comment-page-1</link>
		<dc:creator>Andy Melnikov</dc:creator>
		<pubDate>Fri, 18 Nov 2011 10:50:15 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=98#comment-90755</guid>
		<description>&lt;blockquote&gt;
  &lt;p&gt;Consider that IO includes exception-handling&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;IO also includes concurrency, which is even more troublesome.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<blockquote>
  <p>Consider that IO includes exception-handling</p>
</blockquote>

<p>IO also includes concurrency, which is even more troublesome.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/is-haskell-a-purely-functional-language/comment-page-1#comment-90755</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on functional future values by Mike Sperber</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/9laOUZgv6io/comment-page-1</link>
		<dc:creator>Mike Sperber</dc:creator>
		<pubDate>Thu, 20 Oct 2011 07:22:26 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=73#comment-89133</guid>
		<description>&lt;p&gt;Getting back to my previous comment: I think I understand what the issue is now, and it reveals a deeper problem with this approach to future value:&lt;/p&gt;

&lt;p&gt;You start out by saying that all function futures should be created from simple futures, but of course caching futures violate that principle - at least if they themselves are not created from simple futures. And, at some point, you want to hook up actual external-world actions to get some of that reactivity the "R" in FRP is about, and caching futures are an entry obvious entry point.&lt;/p&gt;

&lt;p&gt;Here's the problem: Caching futures themselves are well-behaved, but caching futures combined with mappend are not: Consider two caching futures &lt;code&gt;f1&lt;/code&gt; and &lt;code&gt;f2&lt;/code&gt;, and  only &lt;code&gt;f1&lt;/code&gt; gets triggered at time &lt;code&gt;t0&lt;/code&gt;.  Mappend them to get future &lt;code&gt;f&lt;/code&gt;. If you ask the (try-future version of) f at time &lt;code&gt;t' &gt; t0&lt;/code&gt;, you get &lt;code&gt;Some&lt;/code&gt; answer. If you ask at &lt;code&gt;MaxBound&lt;/code&gt; (which is greater than &lt;code&gt;t'&lt;/code&gt;), you get no answer, because the system waits for &lt;code&gt;f2&lt;/code&gt;. So monotonicity is violated. That, of course, is also the issue with my version of &lt;code&gt;fToS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The deeper problem, I think, is the fact that the event occurrences the system talks about really refer to the programmatic event (i.e. the &lt;code&gt;SampleVar&lt;/code&gt; being filled), rather than &lt;em&gt;knowledge&lt;/em&gt; about an external event, which only becomes available after it has actually happened. (How do you mappend two futures knowing that they'll become known only after the timestamps that will be attached to them?)&lt;/p&gt;

&lt;p&gt;All solutions I've come up with for this require going back to some notion of partial time. It can be pushed into a smaller corner than before, but it's still there.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Getting back to my previous comment: I think I understand what the issue is now, and it reveals a deeper problem with this approach to future value:</p>

<p>You start out by saying that all function futures should be created from simple futures, but of course caching futures violate that principle &#8211; at least if they themselves are not created from simple futures. And, at some point, you want to hook up actual external-world actions to get some of that reactivity the &#8220;R&#8221; in FRP is about, and caching futures are an entry obvious entry point.</p>

<p>Here&#8217;s the problem: Caching futures themselves are well-behaved, but caching futures combined with mappend are not: Consider two caching futures <code>f1</code> and <code>f2</code>, and  only <code>f1</code> gets triggered at time <code>t0</code>.  Mappend them to get future <code>f</code>. If you ask the (try-future version of) f at time <code>t' &gt; t0</code>, you get <code>Some</code> answer. If you ask at <code>MaxBound</code> (which is greater than <code>t'</code>), you get no answer, because the system waits for <code>f2</code>. So monotonicity is violated. That, of course, is also the issue with my version of <code>fToS</code>.</p>

<p>The deeper problem, I think, is the fact that the event occurrences the system talks about really refer to the programmatic event (i.e. the <code>SampleVar</code> being filled), rather than <em>knowledge</em> about an external event, which only becomes available after it has actually happened. (How do you mappend two futures knowing that they&#8217;ll become known only after the timestamps that will be attached to them?)</p>

<p>All solutions I&#8217;ve come up with for this require going back to some notion of partial time. It can be pushed into a smaller corner than before, but it&#8217;s still there.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-functional-future-values/comment-page-1#comment-89133</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on zippers by conal</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/TDRc6alNdPY/comment-page-1</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Tue, 06 Sep 2011 04:24:41 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=154#comment-86817</guid>
		<description>&lt;p&gt;Robin: I wasn't suggesting that &lt;code&gt;left&lt;/code&gt; &amp; &lt;code&gt;right&lt;/code&gt; are easy to implement. Rather that they might be unnecessary (pure speculation). Do you &lt;em&gt;really&lt;/em&gt; want &lt;code&gt;left&lt;/code&gt; &amp; &lt;code&gt;right&lt;/code&gt; instead of the list (or whatever functor element) of children?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Robin: I wasn&#8217;t suggesting that <code>left</code> &amp; <code>right</code> are easy to implement. Rather that they might be unnecessary (pure speculation). Do you <em>really</em> want <code>left</code> &amp; <code>right</code> instead of the list (or whatever functor element) of children?</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-zippers/comment-page-1#comment-86817</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on zippers by Robin Green</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/l1gs1sxS8KE/comment-page-1</link>
		<dc:creator>Robin Green</dc:creator>
		<pubDate>Mon, 05 Sep 2011 00:15:21 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=154#comment-86752</guid>
		<description>&lt;p&gt;I figured it out. It's necessary to go up, then down, then do a case split on all the possibilities (looking at both the derivative &lt;em&gt;and&lt;/em&gt; the reconstructed upper level). It's not very simple at all!&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I figured it out. It&#8217;s necessary to go up, then down, then do a case split on all the possibilities (looking at both the derivative <em>and</em> the reconstructed upper level). It&#8217;s not very simple at all!</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-zippers/comment-page-1#comment-86752</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on zippers by conal</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/__m9jezbpqQ/comment-page-1</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Sun, 04 Sep 2011 19:42:13 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=154#comment-86746</guid>
		<description>&lt;p&gt;Robin: does the remark following the type of &lt;code&gt;down&lt;/code&gt; answer your question?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since &lt;code&gt;down&lt;/code&gt; yields an &lt;code&gt;f&lt;/code&gt;-collection of locations, we do not need sibling navigation functions (&lt;code&gt;left&lt;/code&gt; &amp; &lt;code&gt;right&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For instance, if &lt;code&gt;f = []&lt;/code&gt;, then &lt;code&gt;down&lt;/code&gt; yields a &lt;em&gt;list&lt;/em&gt; of child zippers, which you can traverse as you like.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Robin: does the remark following the type of <code>down</code> answer your question?</p>

<blockquote>
<p>Since <code>down</code> yields an <code>f</code>-collection of locations, we do not need sibling navigation functions (<code>left</code> &amp; <code>right</code>).</p>
</blockquote>

<p>For instance, if <code>f = []</code>, then <code>down</code> yields a <em>list</em> of child zippers, which you can traverse as you like.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-zippers/comment-page-1#comment-86746</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on zippers by Robin Green</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/ym5VRUI_50Q/comment-page-1</link>
		<dc:creator>Robin Green</dc:creator>
		<pubDate>Sun, 04 Sep 2011 12:30:09 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=154#comment-86731</guid>
		<description>&lt;p&gt;I've been trying to implement this in OCaml, and I kept thinking "How are left and right going to be implemented?" Now that I've come to implement them, I still don't get it. You say that the interface is simpler because it doesn't have left and right - but in order for that argument to hold, it must be simple to move left and right. How do you do it?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I&#8217;ve been trying to implement this in OCaml, and I kept thinking &#8220;How are left and right going to be implemented?&#8221; Now that I&#8217;ve come to implement them, I still don&#8217;t get it. You say that the interface is simpler because it doesn&#8217;t have left and right &#8211; but in order for that argument to hold, it must be simple to move left and right. How do you do it?</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-zippers/comment-page-1#comment-86731</feedburner:origLink></item>
	<item>
		<title>Comment on Is Haskell a purely functional language? by Manuel Chakravarty</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/yaIH95Y7YYY/comment-page-1</link>
		<dc:creator>Manuel Chakravarty</dc:creator>
		<pubDate>Mon, 01 Aug 2011 00:23:02 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=98#comment-84703</guid>
		<description>&lt;p&gt;Vinod, some of it call it "purely functional programming".&lt;/p&gt;

&lt;p&gt;Conal, nice observation about Landin. I have to say "denotative" is an appealing term.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Vinod, some of it call it &#8220;purely functional programming&#8221;.</p>

<p>Conal, nice observation about Landin. I have to say &#8220;denotative&#8221; is an appealing term.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/is-haskell-a-purely-functional-language/comment-page-1#comment-84703</feedburner:origLink></item>
	<item>
		<title>Comment on Another angle on functional future values by Mike Sperber</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/cswgjg1xsv0/comment-page-1</link>
		<dc:creator>Mike Sperber</dc:creator>
		<pubDate>Tue, 12 Jul 2011 09:33:38 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=73#comment-83490</guid>
		<description>&lt;p&gt;I'm not sure I understand the comment about fToS not lending itself to implementation.  Can't you say (rusty Haskell ahead):&lt;/p&gt;

&lt;pre&gt;
fToS f = p (unFuture f maxBound)
  where
   p Nothing -&gt; (maxBound, undefined)
   p (Some sf) -&gt; sf
&lt;/pre&gt;

&lt;p&gt;?&lt;/p&gt;

&lt;p&gt;Sure, you might have to wait, but that's true in general of F.FutureG, no?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I&#8217;m not sure I understand the comment about fToS not lending itself to implementation.  Can&#8217;t you say (rusty Haskell ahead):</p>

<pre>
fToS f = p (unFuture f maxBound)
  where
   p Nothing -&gt; (maxBound, undefined)
   p (Some sf) -&gt; sf
</pre>

<p>?</p>

<p>Sure, you might have to wait, but that&#8217;s true in general of F.FutureG, no?</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/another-angle-on-functional-future-values/comment-page-1#comment-83490</feedburner:origLink></item>
	<item>
		<title>Comment on Parallel tree scanning by composition by conal</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/K1eDOV9z-tg/comment-page-1</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Fri, 17 Jun 2011 17:41:11 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=429#comment-82531</guid>
		<description>&lt;p&gt;Ryan: Oops! Thanks for the catch. I know the laws hold for depth-typed trees, since they're tries (and thus isomorphic to functions, which do satisfy the laws), but I haven't checked the laws for these non-depth-typed trees. I wonder whether they hold with your alteration.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Ryan: Oops! Thanks for the catch. I know the laws hold for depth-typed trees, since they&#8217;re tries (and thus isomorphic to functions, which do satisfy the laws), but I haven&#8217;t checked the laws for these non-depth-typed trees. I wonder whether they hold with your alteration.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/parallel-tree-scanning-by-composition/comment-page-1#comment-82531</feedburner:origLink></item>
	<item>
		<title>Comment on A trie for length-typed vectors by Conal Elliott » Blog Archive » A third view on trees</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/gOQFZHBS_IE/comment-page-1</link>
		<dc:creator>Conal Elliott » Blog Archive » A third view on trees</dc:creator>
		<pubDate>Sat, 04 Jun 2011 21:35:51 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=308#comment-81324</guid>
		<description>&lt;p&gt;[...] Alternatively, make the tree sizes explicit in the types, as in a few recent posts, including A trie for length-typed vectors. (In those posts, I used the terms "right-folded" and "left-folded" in place of [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] Alternatively, make the tree sizes explicit in the types, as in a few recent posts, including A trie for length-typed vectors. (In those posts, I used the terms &quot;right-folded&quot; and &quot;left-folded&quot; in place of [...]</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/a-trie-for-length-typed-vectors/comment-page-1#comment-81324</feedburner:origLink></item>
	<item>
		<title>Comment on Parallel tree scanning by composition by Conal Elliott » Blog Archive » A third view on trees</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/n4LL7ZYIp4U/comment-page-1</link>
		<dc:creator>Conal Elliott » Blog Archive » A third view on trees</dc:creator>
		<pubDate>Sat, 04 Jun 2011 02:46:25 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=429#comment-81247</guid>
		<description>&lt;p&gt;[...] About      « Parallel tree scanning by composition [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] About      &laquo; Parallel tree scanning by composition [...]</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/parallel-tree-scanning-by-composition/comment-page-1#comment-81247</feedburner:origLink></item>
	<item>
		<title>Comment on Parallel tree scanning by composition by Ryan Ingram</title>
		<link>http://feedproxy.google.com/~r/conal-comments/~3/rsFOEf2S2LM/comment-page-1</link>
		<dc:creator>Ryan Ingram</dc:creator>
		<pubDate>Wed, 01 Jun 2011 22:09:37 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=429#comment-80993</guid>
		<description>&lt;p&gt;T2's applicative instance doesn't follow the applicative laws, though.&lt;/p&gt;

&lt;p&gt;for example:&lt;/p&gt;

&lt;p&gt;pure id &lt;*&gt; x  /=  x&lt;/p&gt;

&lt;p&gt;You can fix this by 'cloning' the leaf elements though:&lt;/p&gt;

&lt;p&gt;L2 f &lt;*&gt; B2 (xs :# ys) = B2 (f  xs :# f  ys)&lt;/p&gt;

&lt;p&gt;B2 (fs :# gs) &lt;*&gt; L2 x = B2 (($x)  fs :# ($x)  gs)&lt;/p&gt;

&lt;p&gt;I think a similar trick works for T4.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>T2&#8242;s applicative instance doesn&#8217;t follow the applicative laws, though.</p>

<p>for example:</p>

<p>pure id &lt;*&gt; x  /=  x</p>

<p>You can fix this by &#8216;cloning&#8217; the leaf elements though:</p>

<p>L2 f &lt;*&gt; B2 (xs :# ys) = B2 (f  xs :# f  ys)</p>

<p>B2 (fs :# gs) &lt;*&gt; L2 x = B2 (($x)  fs :# ($x)  gs)</p>

<p>I think a similar trick works for T4.</p>]]></content:encoded>
	<feedburner:origLink>http://conal.net/blog/posts/parallel-tree-scanning-by-composition/comment-page-1#comment-80993</feedburner:origLink></item>
</channel>
</rss>

