<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	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:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Fun with the Lazy State Monad</title>
	<atom:link href="http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/</link>
	<description>Math, Computer Science,  and Education</description>
	<lastBuildDate>Wed, 08 May 2013 14:59:04 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: lpsmith</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-133</link>
		<dc:creator><![CDATA[lpsmith]]></dc:creator>
		<pubDate>Wed, 03 Aug 2011 18:35:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-133</guid>
		<description><![CDATA[In a conversation with Edward Kmett,  he suggested that the Lazy State Monad is, arguably,  not a monad in the categorical sense,  because &lt;code&gt;fmap id ≠ id&lt;/code&gt;.   In particular,   &lt;code&gt;fmap id ⊥ = λ _ → (⊥,⊥)&lt;/code&gt;.]]></description>
		<content:encoded><![CDATA[<p>In a conversation with Edward Kmett,  he suggested that the Lazy State Monad is, arguably,  not a monad in the categorical sense,  because <code>fmap id ≠ id</code>.   In particular,   <code>fmap id ⊥ = λ _ → (⊥,⊥)</code>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Fun with the Lazy State Monad, Part 2 « Melding Monads</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-103</link>
		<dc:creator><![CDATA[Fun with the Lazy State Monad, Part 2 « Melding Monads]]></dc:creator>
		<pubDate>Wed, 25 Aug 2010 10:52:16 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-103</guid>
		<description><![CDATA[If you like this post,  you might also be interested in &lt;a href=&quot;http://blog.melding-monads.com/2010/08/25/fun-with-the-lazy-state-monad-part-2/&quot; rel=&quot;nofollow&quot;&gt;Fun with the Lazy State Monad, Part&#160;2&lt;/a&gt;,  where I combine the Fresh monad with the continuation transformer.]]></description>
		<content:encoded><![CDATA[<p>If you like this post,  you might also be interested in <a href="http://blog.melding-monads.com/2010/08/25/fun-with-the-lazy-state-monad-part-2/" rel="nofollow">Fun with the Lazy State Monad, Part&nbsp;2</a>,  where I combine the Fresh monad with the continuation transformer.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: lpsmith</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-67</link>
		<dc:creator><![CDATA[lpsmith]]></dc:creator>
		<pubDate>Sat, 20 Feb 2010 04:12:25 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-67</guid>
		<description><![CDATA[The problem is that once you apply a continuation transformer to the monad stack itself,  you make the lazy state monad a strict state monad,   and this algorithm will get stuck in an infinite non-productive loop.    It does not matter if it&#039;s a codensity transformer,  or a regular continuation transformer.  The higher-ranked types do not change the termination properties of the program.

One can verify my claim above by installing Edward Kmett&#039;s &lt;a href=&quot;http://hackage.haskell.org/package/category-extras&quot; rel=&quot;nofollow&quot;&gt;category-extras&lt;/a&gt; package,  and applying his Codensity transformer to the original code.    Also,  I think I see what you tried to do with &lt;code&gt;freshCod&lt;/code&gt;,  however,  your code produces a depth-first renumbering,  not breadth-first as is desired.

It&#039;s an interesting idea though;  is it possible to somehow &quot;layer&quot; the monads on each other without resorting to transformers?   Basically,  instead of combining the effects of two monads,  can you use one monad to structure the computation inside another monadic language while keeping them more-or-less separate?]]></description>
		<content:encoded><![CDATA[<p>The problem is that once you apply a continuation transformer to the monad stack itself,  you make the lazy state monad a strict state monad,   and this algorithm will get stuck in an infinite non-productive loop.    It does not matter if it&#8217;s a codensity transformer,  or a regular continuation transformer.  The higher-ranked types do not change the termination properties of the program.</p>
<p>One can verify my claim above by installing Edward Kmett&#8217;s <a href="http://hackage.haskell.org/package/category-extras" rel="nofollow">category-extras</a> package,  and applying his Codensity transformer to the original code.    Also,  I think I see what you tried to do with <code>freshCod</code>,  however,  your code produces a depth-first renumbering,  not breadth-first as is desired.</p>
<p>It&#8217;s an interesting idea though;  is it possible to somehow &#8220;layer&#8221; the monads on each other without resorting to transformers?   Basically,  instead of combining the effects of two monads,  can you use one monad to structure the computation inside another monadic language while keeping them more-or-less separate?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: zygoloid</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-66</link>
		<dc:creator><![CDATA[zygoloid]]></dc:creator>
		<pubDate>Sat, 20 Feb 2010 00:46:21 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-66</guid>
		<description><![CDATA[Looks like you&#039;re secretly working in the Codensity Fresh monad (which is almost the same as ContT Fresh):

&lt;pre&gt;
type FreshCod n = Codensity (Fresh n)

runFreshCod :: Num n =&gt; FreshCod n a -&gt; a
runFreshCod m = runFresh (runCodensity m return)

freshCod :: Num n =&gt; FreshCod n n
freshCod = Codensity fresh

lazyRenum :: Num n =&gt; Tree a b -&gt; Tree n n
lazyRenum = runFreshCod . renumber
   where
     renumber (Leaf    _    )
        = do n &lt;- freshCod
             return (Leaf n)
     renumber (Branch  _ l r)
        = do n &lt;- freshCod
             l&#039; &lt;- renumber l
             r&#039; &lt;- renumber r
             return (Branch n l&#039; r&#039;)
&lt;/pre&gt;]]></description>
		<content:encoded><![CDATA[<p>Looks like you&#8217;re secretly working in the Codensity Fresh monad (which is almost the same as ContT Fresh):</p>
<pre>
type FreshCod n = Codensity (Fresh n)

runFreshCod :: Num n =&gt; FreshCod n a -&gt; a
runFreshCod m = runFresh (runCodensity m return)

freshCod :: Num n =&gt; FreshCod n n
freshCod = Codensity fresh

lazyRenum :: Num n =&gt; Tree a b -&gt; Tree n n
lazyRenum = runFreshCod . renumber
   where
     renumber (Leaf    _    )
        = do n &lt;- freshCod
             return (Leaf n)
     renumber (Branch  _ l r)
        = do n &lt;- freshCod
             l&#39; &lt;- renumber l
             r&#39; &lt;- renumber r
             return (Branch n l&#39; r&#39;)
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: lpsmith</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-51</link>
		<dc:creator><![CDATA[lpsmith]]></dc:creator>
		<pubDate>Thu, 31 Dec 2009 06:22:56 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-51</guid>
		<description><![CDATA[That is very elegant,  my appreciation of applicative functors could be better. :-)

I would contrast this with C++ and Scheme in that their order of evaluation of arguments is not specified.  I wrote a parser in C++ years ago basically using an applicative functor kind of idiom,  only to have to rewrite it in something closer to the monadic style because of this fact.

At first I found this rather frustrating,  although I grew to see it as kind of a good thing,  as you must make dependencies on order explicit, and it allows the compiler to optimize more aggressively.

On the other hand,  the (big) downside is that code happens to work on one compiler can break on another.  Of course,  these specific issues don&#039;t apply to Haskell because effects are tightly controlled,  but it does inform my stylistic tastes.   

With the monadic style it&#039;s easy to specify a right-to-left renumbering,   all you have to do is swap the order of two lines.    However,  I&#039;m not sure the elegance of the applicative style holds up quite as nicely in the face of this change.

But of course,  monadic versus applicative styles is not an all-or-nothing proposition,  and I do think that your decomposition of &lt;code&gt;fresh&lt;/code&gt; into &lt;code&gt;fresh&lt;/code&gt; and &lt;code&gt;down&lt;/code&gt; is probably a good move.]]></description>
		<content:encoded><![CDATA[<p>That is very elegant,  my appreciation of applicative functors could be better. :-)</p>
<p>I would contrast this with C++ and Scheme in that their order of evaluation of arguments is not specified.  I wrote a parser in C++ years ago basically using an applicative functor kind of idiom,  only to have to rewrite it in something closer to the monadic style because of this fact.</p>
<p>At first I found this rather frustrating,  although I grew to see it as kind of a good thing,  as you must make dependencies on order explicit, and it allows the compiler to optimize more aggressively.</p>
<p>On the other hand,  the (big) downside is that code happens to work on one compiler can break on another.  Of course,  these specific issues don&#8217;t apply to Haskell because effects are tightly controlled,  but it does inform my stylistic tastes.   </p>
<p>With the monadic style it&#8217;s easy to specify a right-to-left renumbering,   all you have to do is swap the order of two lines.    However,  I&#8217;m not sure the elegance of the applicative style holds up quite as nicely in the face of this change.</p>
<p>But of course,  monadic versus applicative styles is not an all-or-nothing proposition,  and I do think that your decomposition of <code>fresh</code> into <code>fresh</code> and <code>down</code> is probably a good move.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Twan van Laarhoven</title>
		<link>http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/#comment-50</link>
		<dc:creator><![CDATA[Twan van Laarhoven]]></dc:creator>
		<pubDate>Thu, 31 Dec 2009 03:55:17 +0000</pubDate>
		<guid isPermaLink="false">http://blog.melding-monads.com/?p=154#comment-50</guid>
		<description><![CDATA[I would have split the fresh function into

&lt;pre&gt;
    fresh :: Num n =&gt; Fresh n n
    down :: Fresh n a -&gt; Fresh n a

    fresh = do
       (n:ns) &lt;- get
       put (n+1 : ns)
       return n
    down f = do
       (n:ns) &lt;- get
       put ns
       x &lt;- f
       ns&#039; &lt;- get
       put (n:ns&#039;)
       return x
&lt;/pre&gt;

This is more like a regular fresh name supply, and allows renumber to be written in an applicative style, like so:

&lt;pre&gt;
    renumber (Leaf    _    ) = Leaf &lt;$&gt; fresh
    renumber (Branch  _ l r) = Branch &lt;$&gt; fresh &lt;*&gt; (down $ renumber l) &lt;*&gt; (down $ renumber r)
&lt;/pre&gt;]]></description>
		<content:encoded><![CDATA[<p>I would have split the fresh function into</p>
<pre>
    fresh :: Num n =&gt; Fresh n n
    down :: Fresh n a -&gt; Fresh n a

    fresh = do
       (n:ns) &lt;- get
       put (n+1 : ns)
       return n
    down f = do
       (n:ns) &lt;- get
       put ns
       x &lt;- f
       ns&#39; &lt;- get
       put (n:ns&#39;)
       return x
</pre>
<p>This is more like a regular fresh name supply, and allows renumber to be written in an applicative style, like so:</p>
<pre>
    renumber (Leaf    _    ) = Leaf &lt;$&gt; fresh
    renumber (Branch  _ l r) = Branch &lt;$&gt; fresh &lt;*&gt; (down $ renumber l) &lt;*&gt; (down $ renumber r)
</pre>
]]></content:encoded>
	</item>
</channel>
</rss>
