<div dir="ltr">My mistake. These rules are still in Control.Monad. I just scrolled right past them.<div><br></div><div>-Edward</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Apr 20, 2014 at 5:04 PM, Edward Kmett <span dir="ltr"><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@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">The principled objection to giving these combinators the "obvious" names in Control.Monad is that that module has historically held to a detailed convention that these proposed names unfortunately don't fit. =/<div>

<br></div><div><div><div><table cellspacing="0" cellpadding="0" style="font-size:medium;width:1260px;font-family:sans-serif;border-width:0px"><tbody><tr><td style="border-width:0px;padding-top:2px;padding-left:10px">
<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote"><font size="1">The functions in this library use the following naming conventions:</font><ul>

<li><font size="1">A postfix '<tt>M</tt>' always stands for a function in the Kleisli category: The monad type constructor <tt>m</tt> is added to function results (modulo currying) and nowhere else. So, for example,</font></li>

</ul><font size="1">  filter  ::              (a ->   Bool) -> [a] ->   [a]<br></font><font size="1">  filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]</font><ul><li><font size="1">A postfix '<tt>_</tt>' changes the result type from <tt>(m a)</tt> to <tt>(m ())</tt>. Thus, for example:</font></li>

</ul><font size="1">  sequence  :: Monad m => [m a] -> m [a]<br> </font><font size="1">  sequence_ :: Monad m => [m a] -> m () </font><ul><li><font size="1">A prefix '<tt>m</tt>' generalizes an existing function to a monadic form. Thus, for example:</font></li>

</ul><font size="1">  sum  :: Num a       => [a]   -> a<br></font><font size="1">  msum :: MonadPlus m => [m a] -> m a</font></blockquote></td></tr><tr></tr></tbody></table></div></div><div><br></div><div><div>

That said, if we do adopt them, they probably should get the ifM, whenM, unlessM names.</div><div><br></div><div>I don't think the convention has been documented in Control.Monad itself for years.</div><span class="HOEnZb"><font color="#888888"><div>
</div></font></span></div><span class="HOEnZb"><font color="#888888">
<div><br></div></font></span></div><span class="HOEnZb"><font color="#888888"><div>-Edward</div><div><br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">
On Sun, Apr 20, 2014 at 4:26 PM, Mario Pastorelli <span dir="ltr"><<a href="mailto:pastorelli.mario@gmail.com" target="_blank">pastorelli.mario@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Herbert,<br>
<br>
in general I like pattern matching but not when boolean values are involved. Your code is nice but, in my opinion, still far from the elegance of<br>
<br>
f = unlessM (doesDirectoryExist path) $ do<div><br>
          putStrLn $ "Creating directory " ++ path<br>
          createDirectory path<br>
<br></div>
In particular, note that I don't have to take care of the False case and the code doesn't have boilerplate.<br>
<br>
While your solution is more general, I would like to point out that when and unless are so useful that they got their own functions in the library instead of relying on pattern matching. I consider ifM, whenM and unlessM as alternate versions of existing functions.<div>

<div><br>
<br>
On 04/20/2014 09:59 PM, Herbert Valerio Riedel wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Mario,<br>
<br>
On 2014-04-20 at 21:10:03 +0200, Mario Pastorelli wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I would like to propose the addition of two new combinators to<br>
Control.Monad:<br>
<br>
ifM :: (Monad m) => m Bool -> m a -> m a -> m a<br>
whenM :: (Monad m) => m Bool -> m () -> m ()<br>
</blockquote>
[...]<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
f = do<br>
     dirDoesntExist <- not <$> doesDirectoryExist path<br>
     when dirDoesntExist $ do<br>
       putStrLn $ "Creating directory " ++ path<br>
       createDirectory path<br>
</blockquote>
While I'm neutral on this proposal, I'd like to remind that LambdaCase<br>
may be useful to avoid temporary variables as well (and is even more<br>
useful for types other than Bool):<br>
<br>
   f = doesDirectoryExist path >>= \case<br>
         True  -> return ()<br>
         False -> do<br>
           putStrLn $ "Creating directory " ++ path<br>
           createDirectory path<br>
   Cheers,<br>
   hvr<br>
</blockquote>
<br>
______________________________<u></u>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>