<div dir="ltr"><div>Sometimes it is easier to write it with do notation and then rewrite it back in normal terms:<br><br>mapM :: Monad m => (a -> m b) -> [a] -> m [b]<br>mapM _ [] = return []<br>mapM f (x:xs) = do<br>  x' <- f x<br>  xs' <- mapM f xs<br>  return $ x':xs'<br><br></div><div>You can rewrite the second part step by step as:<br></div><div><br>mapM f (x:xs) = f x >>= \x' -> mapM f xs >>= \xs' -> return (x' : xs')<br><br></div>Also the base package does not use do notation.  It defines it much more elegantly:<br><pre><span class="">mapM</span>            <span class="">::</span> <span class="">Monad</span> <span class="">m</span> <span class="">=></span> <span class="">(</span><span class="">a</span> <span class="">-></span> <span class="">m</span> <span class="">b</span><span class="">)</span> <span class="">-></span> <span class="">[</span><span class="">a</span><span class="">]</span> <span class="">-></span> <span class="">m</span> <span class="">[</span><span class="">b</span><span class="">]</span><span class=""></span>
<a name="line-111"></a><span class="">mapM</span> <span class="">f</span> <span class="">as</span>       <span class="">=</span>  <span class="">sequence</span> <span class="">(</span><span class="">map</span> <span class="">f</span> <span class="">as</span><span class="">)</span></pre><br><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 20, 2015 at 3:52 PM, Vale Cofer-Shabica <span dir="ltr"><<a href="mailto:vale.cofershabica@gmail.com" target="_blank">vale.cofershabica@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello all,<br><br>I've been reading through "Tackling the Awkward Squad" [1] and am implementing the definitions "left as exercises" as I go. For section 2.2, I define:<br><br>    putLine :: [Char] -> IO ()<br>    putLine :: mapM_ putChar<br><br>where<br><br>    mapM_ :: Monad m => (a -> m b) -> a -> m ()<br>    mapM_ f [] = return ()<br>    mapM_ f (x:xs) = (f x) >> (mapM_ f xs)<br><br>which works without difficulty. For the sake of learning, I decided to implement mapM as well. My definition (below) works, but seems really in-elegant. I checked the prelude source and found mapM defined in terms of sequence, which has some do-notation I'm not so clear on. I'm trying to avoid using do notation in my implementation because it still feels like magic. I'll work on de-sugaring do notation again once I have a solid handle on (>>=), (>>), and return. Any suggestions for cleaning this up would be much appreciated!<br><br>    mapM :: Monad m => (a -> m b) -> [a] -> m [b]<br>    mapM f [] = return []<br>    mapM f (x:xs) = consMM (f x) (mapM f xs)<br><br>    consMM :: Monad m => m a -> m [a] -> m [a]<br>    consMM mx mxs = mx >>= ((flip consM)  mxs) where<br>        consM x mxs = mxs>>=(\xs -> return (x:xs))<br><br>Thank you,<br>vale<br><br>[1] Suggested by apfelmus in a recent email to the list:<br><a href="http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/" target="_blank">http://research.microsoft.com/en-us/um/people/simonpj/papers/marktoberdorf/</a><br></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>