<?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/"
		>
<channel>
	<title>Comments on: Modular Monad Transformers</title>
	<atom:link href="http://sneezy.cs.nott.ac.uk/fplunch/weblog/?feed=rss2&#038;p=111" rel="self" type="application/rss+xml" />
	<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111</link>
	<description>abstracting the pain away</description>
	<lastBuildDate>Tue, 17 May 2011 07:05:56 +0100</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
	<item>
		<title>By: Mauro Jaskelioff</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22050</link>
		<dc:creator>Mauro Jaskelioff</dc:creator>
		<pubDate>Sat, 06 Sep 2008 09:29:37 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22050</guid>
		<description>Actually you don&#039;t need any boilerplate definitions. If all the operations are algebraic (for example, get and put) then you can write:

instance (MonadState s m, MonadTrans t, Monad (t m)) =&gt; MonadState s (t m) where
       get = lift get
       put = lift . put

and the boilerplate is gone. The surprising thing is that you can do the same for other operations. I showed above the simplest example that I know of, which is for ask and local, but the same technique can be applied to other operations. There is a general technique which allows you to determine the appropriate monad in which catchError is algebraic (catchError is not algebraic with the current semantics). This same technique yields State as the appropriate monad for local.</description>
		<content:encoded><![CDATA[<p>Actually you don&#8217;t need any boilerplate definitions. If all the operations are algebraic (for example, get and put) then you can write:</p>
<p>instance (MonadState s m, MonadTrans t, Monad (t m)) => MonadState s (t m) where<br />
       get = lift get<br />
       put = lift . put</p>
<p>and the boilerplate is gone. The surprising thing is that you can do the same for other operations. I showed above the simplest example that I know of, which is for ask and local, but the same technique can be applied to other operations. There is a general technique which allows you to determine the appropriate monad in which catchError is algebraic (catchError is not algebraic with the current semantics). This same technique yields State as the appropriate monad for local.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Menendez</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22032</link>
		<dc:creator>Dave Menendez</dc:creator>
		<pubDate>Fri, 05 Sep 2008 16:48:40 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22032</guid>
		<description>Again, lifting get and set through a monad transformer is already trivial. Instead of two boilerplate definitions (&quot;lift get&quot; and &quot;lift . set&quot;), you have one boilerplate definition for the monad morphism (something like &quot;lift . liftState&quot;). 

The example of appendL is more compelling.

What about other operations? I&#039;m guessing that throwError is algebraic and catchError is not.</description>
		<content:encoded><![CDATA[<p>Again, lifting get and set through a monad transformer is already trivial. Instead of two boilerplate definitions (&#8220;lift get&#8221; and &#8220;lift . set&#8221;), you have one boilerplate definition for the monad morphism (something like &#8220;lift . liftState&#8221;). </p>
<p>The example of appendL is more compelling.</p>
<p>What about other operations? I&#8217;m guessing that throwError is algebraic and catchError is not.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mauro Jaskelioff</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22031</link>
		<dc:creator>Mauro Jaskelioff</dc:creator>
		<pubDate>Fri, 05 Sep 2008 15:37:11 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22031</guid>
		<description>The fact that defining Reader in term of State is trivial (and this is a good thing). What you gain is that you don&#039;t need to define, ask and local for every monad transformer!

Also, the monad morphism from [] into another monad is exactly what you get with any monad transformer. For example,
 
lift :: [a] -&gt; StateT s [a].</description>
		<content:encoded><![CDATA[<p>The fact that defining Reader in term of State is trivial (and this is a good thing). What you gain is that you don&#8217;t need to define, ask and local for every monad transformer!</p>
<p>Also, the monad morphism from [] into another monad is exactly what you get with any monad transformer. For example,</p>
<p>lift :: [a] -> StateT s [a].</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Menendez</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22030</link>
		<dc:creator>Dave Menendez</dc:creator>
		<pubDate>Fri, 05 Sep 2008 15:16:47 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22030</guid>
		<description>So local&#039; is just set in disguise.

local&#039; f m = get &gt;&gt;= \s -&gt; set (f s) &gt;&gt; m

I don&#039;t mean to be negative, but I&#039;m not seeing how this technique makes anything simpler. Defining a state reader in terms of a state transformer is already trivial, and defining a morphism from [] into a given monad seems at least as complicated as defining mzero and mplus directly.</description>
		<content:encoded><![CDATA[<p>So local&#8217; is just set in disguise.</p>
<p>local&#8217; f m = get &gt;&gt;= \s -&gt; set (f s) &gt;&gt; m</p>
<p>I don&#8217;t mean to be negative, but I&#8217;m not seeing how this technique makes anything simpler. Defining a state reader in terms of a state transformer is already trivial, and defining a morphism from [] into a given monad seems at least as complicated as defining mzero and mplus directly.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mauro Jaskelioff</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22028</link>
		<dc:creator>Mauro Jaskelioff</dc:creator>
		<pubDate>Fri, 05 Sep 2008 10:56:58 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22028</guid>
		<description>(accidentally pressed return, should be Reader&#039; and not Reader, local&#039; and not local, and ask&#039; and not ask).
reallocal is not algebraic, and hence, not liftable. However, it is actually defined for any monad which supports &lt;code&gt;ask&#039;&lt;/code&gt; and &lt;code&gt;local&#039;&lt;/code&gt; and those are liftable.

Sorry for all the confusion.</description>
		<content:encoded><![CDATA[<p>(accidentally pressed return, should be Reader&#8217; and not Reader, local&#8217; and not local, and ask&#8217; and not ask).<br />
reallocal is not algebraic, and hence, not liftable. However, it is actually defined for any monad which supports <code>ask'</code> and <code>local'</code> and those are liftable.</p>
<p>Sorry for all the confusion.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mauro Jaskelioff</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22027</link>
		<dc:creator>Mauro Jaskelioff</dc:creator>
		<pubDate>Fri, 05 Sep 2008 10:49:54 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22027</guid>
		<description>Ugh! I shouldn&#039;t post things when I&#039;m tired.

Dave: As you say, the correct functor for local is the pair 
S a = (r-&gt;r, a), and of course local is the curried version of 
S (Reader r a) -&gt; Reader r a.

The function &lt;code&gt;local&#039;&lt;/code&gt; is algebraic, and its semantics will be preserved by the liftings However, as you mention, the semantics of local&#039; are not the same as those of local (I admit the name is totally misleading). You can get the semantics of the old local in the following manner:

&lt;code&gt;
reallocal :: (r-&gt;r) -&gt; Reader r a -&gt; Reader r a
reallocal f m = do 
old &lt;- ask
                   a &lt;- local f m
                   local (const old) (return a)
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Ugh! I shouldn&#8217;t post things when I&#8217;m tired.</p>
<p>Dave: As you say, the correct functor for local is the pair<br />
S a = (r->r, a), and of course local is the curried version of<br />
S (Reader r a) -> Reader r a.</p>
<p>The function <code>local'</code> is algebraic, and its semantics will be preserved by the liftings However, as you mention, the semantics of local&#8217; are not the same as those of local (I admit the name is totally misleading). You can get the semantics of the old local in the following manner:</p>
<p><code><br />
reallocal :: (r->r) -> Reader r a -> Reader r a<br />
reallocal f m = do<br />
old < - ask<br />
                   a <- local f m<br />
                   local (const old) (return a)<br />
</code></code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mauro Jaskelioff</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22022</link>
		<dc:creator>Mauro Jaskelioff</dc:creator>
		<pubDate>Fri, 05 Sep 2008 08:19:50 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22022</guid>
		<description>Thanks, Luke. I think you are right. The law should be,

h (&gt;&gt;= (&gt;&gt;=f)) = h . fmap (&gt;&gt;=(&gt;&gt;=f))

or equivalently

join . h = h . fmap join

(I&#039;m going to edit it in the main post)</description>
		<content:encoded><![CDATA[<p>Thanks, Luke. I think you are right. The law should be,</p>
<p>h (>>= (>>=f)) = h . fmap (>>=(>>=f))</p>
<p>or equivalently</p>
<p>join . h = h . fmap join</p>
<p>(I&#8217;m going to edit it in the main post)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Menendez</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22018</link>
		<dc:creator>Dave Menendez</dc:creator>
		<pubDate>Fri, 05 Sep 2008 05:16:20 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22018</guid>
		<description>I&#039;m confused by the analysis of local. First, if S a = (r -&gt; r) -&gt; a, then S (Reader r a) -&gt; Reader r a = ((r -&gt; r) -&gt; Reader r a) -&gt; Reader r a, which is not the type of local. Maybe S a = (r -&gt; r, a)?

Second, local&#039; doesn&#039;t seem to act like local. If I understand the given definition, then in local&#039; f e1 &gt;&gt;= e2, the changed environment created by f will be visible in e1 and e2, instead of just e1.</description>
		<content:encoded><![CDATA[<p>I&#8217;m confused by the analysis of local. First, if S a = (r -&gt; r) -&gt; a, then S (Reader r a) -&gt; Reader r a = ((r -&gt; r) -&gt; Reader r a) -&gt; Reader r a, which is not the type of local. Maybe S a = (r -&gt; r, a)?</p>
<p>Second, local&#8217; doesn&#8217;t seem to act like local. If I understand the given definition, then in local&#8217; f e1 &gt;&gt;= e2, the changed environment created by f will be visible in e1 and e2, instead of just e1.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Luke Palmer</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22007</link>
		<dc:creator>Luke Palmer</dc:creator>
		<pubDate>Thu, 04 Sep 2008 21:57:32 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22007</guid>
		<description>Upon further investigation, it looks like your law is incorrect.  I think you mean:


h &gt;=&gt; f = h . fmap (&gt;&gt;= f)
</description>
		<content:encoded><![CDATA[<p>Upon further investigation, it looks like your law is incorrect.  I think you mean:</p>
<p>h &gt;=&gt; f = h . fmap (&gt;&gt;= f)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Luke Palmer</title>
		<link>http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22005</link>
		<dc:creator>Luke Palmer</dc:creator>
		<pubDate>Thu, 04 Sep 2008 21:49:04 +0000</pubDate>
		<guid isPermaLink="false">http://sneezy.cs.nott.ac.uk/fplunch/weblog/?p=111#comment-22005</guid>
		<description>Very nice work!  I have been wondering about this and related problems recently, and I would call this a fine result.  Thanks!</description>
		<content:encoded><![CDATA[<p>Very nice work!  I have been wondering about this and related problems recently, and I would call this a fine result.  Thanks!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
