Oops, typos:<div><br></div><div>main = lst &gt;&gt;= sequenceMTAll . map (getB&#39; &gt;=&gt; getC&#39;)</div><div><br></div><div>(and forget about lst&#39;)</div><div><br clear="all">Mike S Craig<br>(908) 328 8030<br>
<br><br><div class="gmail_quote">On Thu, Sep 15, 2011 at 1:49 AM, Michael Craig <span dir="ltr">&lt;<a href="mailto:mkscrg@gmail.com">mkscrg@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im"><span style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">Alright, I return from the land of transformers with a solution:</span><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


<br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


import Control.Monad.Trans.Class</div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">import Control.Monad.Trans.Maybe</div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


<br></div></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">main = sequenceMTAll (lst&#39; &gt;&gt;= map (getB&#39; &gt;=&gt; getC&#39;))</div><div class="im">

<div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">
<br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><div>lst&#39; = lift lst :: MaybeT m [a]</div><div>getB&#39; = MaybeT . getMB</div><div>
getC&#39; = lift . getC</div></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


<div>sequenceMTAll :: (Monad m) =&gt; [MaybeT m a] -&gt; m [a]</div><div>sequenceMTAll (x:xs) = do</div><div>    y &lt;- runMaybeT x</div><div>    case y of</div><div>      Nothing -&gt; sequenceMTAll xs</div><div>      Just z -&gt; sequenceMTAll xs &gt;&gt;= return . (z:)</div>


<div>sequenceMTAll [] = return []</div></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


<br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">(Of course in real code I&#39;d just modify lst, getMB, getC, etc. to fit the new types. The crux here is sequenceMTAll.)</div>


<div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><br></div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)">


Am I abusing Maybe too much?</div><div style="color:rgb(34, 34, 34);font-family:arial, sans-serif;font-size:13px;background-color:rgb(255, 255, 255)"><br></div></div><div class="im">Mike S Craig<br><a href="tel:%28908%29%20328%208030" value="+19083288030" target="_blank">(908) 328 8030</a><br>


<br><br></div><div><div></div><div class="h5"><div class="gmail_quote">On Thu, Sep 15, 2011 at 1:15 AM, Brent Yorgey <span dir="ltr">&lt;<a href="mailto:byorgey@seas.upenn.edu" target="_blank">byorgey@seas.upenn.edu</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Wed, Sep 14, 2011 at 09:21:04PM -0400, Michael Craig wrote:<br>
&gt; Brent: Thanks for reminding me about (&gt;=&gt;). Far more readable! But regarding<br>
&gt; the sequence thing: I can think of all sorts of reasons why we&#39;d want to do<br>
&gt; a single traversal. How about when lst is long or infinite? In general, it&#39;s<br>
&gt; more useful to produce output incrementally than all at once at the<br>
&gt; end.<br>
<br>
</div>Yes, producing output incrementally is great!  My point is that<br>
usually laziness will take care of it for you, without having to<br>
worry about it specifically.<br>
<br>
In this particular case, most monads will not actually allow<br>
incremental processing anyway.  For example, suppose m = Maybe.  Then<br>
when mapping getMB over lst, any particular element could cause the<br>
whole computation to fail.  So we cannot output anything based on the<br>
first elements in the list until we have processed the entire list,<br>
because until we get to the very end of the list we do not know<br>
whether to begin by outputting &#39;Just&#39; or &#39;Nothing&#39;.<br>
<font color="#888888"><br>
-Brent<br>
</font><div><div></div><div><br>
&gt;<br>
&gt; Mike S Craig<br>
&gt; <a href="tel:%28908%29%20328%208030" value="+19083288030" target="_blank">(908) 328 8030</a><br>
&gt;<br>
&gt;<br>
&gt; On Wed, Sep 14, 2011 at 8:18 PM, Brent Yorgey &lt;<a href="mailto:byorgey@seas.upenn.edu" target="_blank">byorgey@seas.upenn.edu</a>&gt;wrote:<br>
&gt;<br>
&gt; &gt; On Wed, Sep 14, 2011 at 06:48:29PM -0400, Michael Craig wrote:<br>
&gt; &gt; &gt; Say we&#39;ve got these types<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; lst :: m [a]<br>
&gt; &gt; &gt; getMB :: a -&gt; m (Maybe b)<br>
&gt; &gt; &gt; getC :: b -&gt; m c<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; and we want to map getMB and getC over the elements of lst, all the while<br>
&gt; &gt; &gt; discarding elements x where getMB x == Nothing.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; (This could be generalized more by replacing Maybe with some monad m&#39;,<br>
&gt; &gt; but<br>
&gt; &gt; &gt; let&#39;s run with Maybe because it&#39;s easy to talk about.)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; The best I&#39;ve got (after some help on IRC) is this not-so-easy-to-read<br>
&gt; &gt; &gt; oneliner:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; lst &gt;&gt;= (\x -&gt; mapM (liftM (liftM getC) (getMB x)) &gt;&gt;= sequence<br>
&gt; &gt; &gt; . catMaybes<br>
&gt; &gt;<br>
&gt; &gt; How about this:<br>
&gt; &gt;<br>
&gt; &gt;  lst &gt;&gt;= (mapM getMB &gt;=&gt; (return . catMaybes) &gt;=&gt; mapM getC)<br>
&gt; &gt;<br>
&gt; &gt; Everyone always forgets about (&gt;=&gt;).<br>
&gt; &gt;<br>
&gt; &gt; &gt; This is hard to read, but it&#39;s also bad because we run sequence twice<br>
&gt; &gt; (once<br>
&gt; &gt; &gt; inside of mapM). If we want to do multiple things to each element of lst,<br>
&gt; &gt; it<br>
&gt; &gt; &gt; would be nice to process each element completely before moving on to the<br>
&gt; &gt; &gt; next.<br>
&gt; &gt;<br>
&gt; &gt; I wouldn&#39;t worry about running sequence twice.  Processing things by<br>
&gt; &gt; chaining whole-structure transformations is the Haskell Way (tm).  All<br>
&gt; &gt; that business about &quot;doing only one traversal&quot; is for people<br>
&gt; &gt; programming in strict languages to worry about. The compiler can often<br>
&gt; &gt; turn a chain of wholesale transformations into a single traversal<br>
&gt; &gt; anyway.  In short, I see no particular reason why it is &quot;nice&quot; to<br>
&gt; &gt; process each element completely before moving on.  Isn&#39;t it nicer to<br>
&gt; &gt; be able to think in a more modular style?<br>
&gt; &gt;<br>
&gt; &gt; -Brent<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Beginners mailing list<br>
&gt; &gt; <a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
&gt; &gt; <a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
&gt; &gt;<br>
</div></div></blockquote></div><br>
</div></div></blockquote></div><br></div>