<span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">Brent: Thanks for reminding me about (>=>). Far more readable! But regarding the sequence thing: I can think of all sorts of reasons why we'd want to do a single traversal. How about when lst is long or infinite? In general, it's more useful to produce output incrementally than all at once at the end.</span><div>
<font color="#222222" face="arial, sans-serif"><br clear="all"></font>Mike S Craig<br>(908) 328 8030<br>
<br><br><div class="gmail_quote">On Wed, Sep 14, 2011 at 8:18 PM, Brent Yorgey <span dir="ltr"><<a href="mailto:byorgey@seas.upenn.edu">byorgey@seas.upenn.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On Wed, Sep 14, 2011 at 06:48:29PM -0400, Michael Craig wrote:<br>
> Say we've got these types<br>
><br>
> lst :: m [a]<br>
> getMB :: a -> m (Maybe b)<br>
> getC :: b -> m c<br>
><br>
> and we want to map getMB and getC over the elements of lst, all the while<br>
> discarding elements x where getMB x == Nothing.<br>
><br>
> (This could be generalized more by replacing Maybe with some monad m', but<br>
> let's run with Maybe because it's easy to talk about.)<br>
><br>
> The best I've got (after some help on IRC) is this not-so-easy-to-read<br>
> oneliner:<br>
><br>
> lst >>= (\x -> mapM (liftM (liftM getC) (getMB x)) >>= sequence<br>
> . catMaybes<br>
<br>
</div>How about this:<br>
<br>
lst >>= (mapM getMB >=> (return . catMaybes) >=> mapM getC)<br>
<br>
Everyone always forgets about (>=>).<br>
<div class="im"><br>
> This is hard to read, but it's also bad because we run sequence twice (once<br>
> inside of mapM). If we want to do multiple things to each element of lst, it<br>
> would be nice to process each element completely before moving on to the<br>
> next.<br>
<br>
</div>I wouldn't worry about running sequence twice. Processing things by<br>
chaining whole-structure transformations is the Haskell Way (tm). All<br>
that business about "doing only one traversal" is for people<br>
programming in strict languages to worry about. The compiler can often<br>
turn a chain of wholesale transformations into a single traversal<br>
anyway. In short, I see no particular reason why it is "nice" to<br>
process each element completely before moving on. Isn't it nicer to<br>
be able to think in a more modular style?<br>
<font color="#888888"><br>
-Brent<br>
</font><div><div></div><div class="h5"><br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div>