Yes, they are. That&#39;s what perhaps Neil Mitchell means by<br><br>mapM_ putStrLn == putStr . unlines<br><br>And whether the trailing newline is to be called the last blank line depends upon the convention; The string that is output in both the cases contains a single newline character. Are you calling that a blank line at end?<br>
<br>And I actually meant to reply to haskell-cafe as well; omitted haskell-cafe by mistake. Anyway, you got the same answer from two people! This time I am including haskell-cafe in the recipients.<br><br>Regards,<br>Abhay<br>
<br><div class="gmail_quote">On Mon, Apr 14, 2008 at 4:05 PM, Benjamin L. Russell &lt;<a href="mailto:dekudekuplex@yahoo.com">dekudekuplex@yahoo.com</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Abhay Parvate,<br>
<br>
Thank you; that answered my question.<br>
<br>
Then, the following two lines of code should be<br>
equivalent:<br>
<br>
In hanoi.hs:<br>
<div class="Ih2E3d">hanoi n = mapM_ putStrLn (hanoi_helper &#39;a&#39; &#39;b&#39; &#39;c&#39; n)<br>
<br>
</div>In hanoi_unlines.hs:<br>
hanoi n = putStr (unlines(hanoi_helper &#39;a&#39; &#39;b&#39; &#39;c&#39; n))<br>
<br>
I tested them both out on WinHugs (Version Sep 2006);<br>
they both generated one blank line at the end.<br>
<font color="#888888"><br>
Benjamin L. Russell<br>
</font><div><div></div><div class="Wj3C7c"><br>
--- Abhay Parvate &lt;<a href="mailto:abhay.parvate@gmail.com">abhay.parvate@gmail.com</a>&gt; wrote:<br>
<br>
&gt; unlines puts newline after each string; putStrLn<br>
&gt; puts newline after the<br>
&gt; given string. As a result, the output contains two<br>
&gt; newlines in the end. You<br>
&gt; can use putStr instead, since the resultant string<br>
&gt; from &#39;unlines&#39; will have<br>
&gt; a newline at the end.<br>
&gt;<br>
&gt; On Mon, Apr 14, 2008 at 2:12 PM, Benjamin L. Russell<br>
&gt; &lt;<a href="mailto:dekudekuplex@yahoo.com">dekudekuplex@yahoo.com</a>&gt;<br>
&gt; wrote:<br>
&gt;<br>
&gt; &gt; Ok; much better. &nbsp;Here&#39;s my new type signature and<br>
&gt; &gt; definition:<br>
&gt; &gt;<br>
&gt; &gt; hanoi.hs:<br>
&gt; &gt; hanoi :: Int -&gt; IO ()<br>
&gt; &gt; hanoi n = mapM_ putStrLn (hanoi_helper &#39;a&#39; &#39;b&#39; &#39;c&#39;<br>
&gt; n)<br>
&gt; &gt;<br>
&gt; &gt; hanoi_helper :: Char -&gt; Char -&gt; Char -&gt; Int -&gt;<br>
&gt; &gt; [String]<br>
&gt; &gt; hanoi_helper source using dest n<br>
&gt; &gt; &nbsp; &nbsp;| n == 1 = [&quot;Move &quot; ++ show source ++ &quot; to &quot; ++<br>
&gt; &gt; show dest ++ &quot;.&quot;]<br>
&gt; &gt; &nbsp; &nbsp;| otherwise = hanoi_helper source dest using<br>
&gt; (n-1)<br>
&gt; &gt;<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;++ hanoi_helper source using dest<br>
&gt; 1<br>
&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ++ hanoi_helper using<br>
&gt; source<br>
&gt; &gt; dest (n-1)<br>
&gt; &gt;<br>
&gt; &gt; Then in WinHugs (Version Sep 2006):<br>
&gt; &gt;<br>
&gt; &gt; Hugs&gt; :load hanoi.hs<br>
&gt; &gt; Main&gt; hanoi 2<br>
&gt; &gt; Move &#39;a&#39; to &#39;b&#39;.<br>
&gt; &gt; Move &#39;a&#39; to &#39;c&#39;.<br>
&gt; &gt; Move &#39;b&#39; to &#39;c&#39;.<br>
&gt; &gt;<br>
&gt; &gt; Great!<br>
&gt; &gt;<br>
&gt; &gt; One minor question: &nbsp;I tried out both of your<br>
&gt; &gt; following suggestions:<br>
&gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; mapM_ putStrLn (hanoi 2) -- outputs each<br>
&gt; move<br>
&gt; &gt; &gt; in a new line<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; putStrLn (unlines (hanoi 2)) -- same as<br>
&gt; &gt; &gt; previous line<br>
&gt; &gt;<br>
&gt; &gt; and discovered that putStrLn with unlines (the<br>
&gt; lower<br>
&gt; &gt; option) in fact generates one extra blank line at<br>
&gt; the<br>
&gt; &gt; end. &nbsp;Just curious as to why....<br>
&gt; &gt;<br>
&gt; &gt; Benjamin L. Russell<br>
&gt; &gt;<br>
&gt; &gt; --- Tillmann Rendel &lt;<a href="mailto:rendel@daimi.au.dk">rendel@daimi.au.dk</a>&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt; &gt; Benjamin L. Russell wrote:<br>
&gt; &gt; &gt; &gt; but got stuck on outputting newlines as part<br>
&gt; of<br>
&gt; &gt; &gt; the string;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; quoting is done by the show function in Haskell,<br>
&gt; so<br>
&gt; &gt; &gt; you have to take<br>
&gt; &gt; &gt; care to avoid calling show. your code calls show<br>
&gt; at<br>
&gt; &gt; &gt; two positions:<br>
&gt; &gt; &gt; (1) when you insert the newline into the string<br>
&gt; &gt; &gt; (2) when you output the string<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; with respect to (1):<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; you use (show &#39;\n&#39;) to create a newline-only<br>
&gt; string,<br>
&gt; &gt; &gt; which produces a<br>
&gt; &gt; &gt; machine-readable (!) textual representation of<br>
&gt; &#39;\n&#39;.<br>
&gt; &gt; &gt; try the difference<br>
&gt; &gt; &gt; between<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; &#39;\n&#39;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; and<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; show &#39;\n&#39;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; to see what I mean. instead of using (show<br>
&gt; &#39;\n&#39;),<br>
&gt; &gt; &gt; you should simply use<br>
&gt; &gt; &gt; &quot;\n&quot; to encode the string of length 1 containing<br>
&gt; a<br>
&gt; &gt; &gt; newline character.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; with respect to (2):<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; the type of your top-level expression is String,<br>
&gt; &gt; &gt; which is automatically<br>
&gt; &gt; &gt; print&#39;ed by the interpreter. but print x =<br>
&gt; putStrLn<br>
&gt; &gt; &gt; (show x), so there<br>
&gt; &gt; &gt; is another call to show at this point. to avoid<br>
&gt; this<br>
&gt; &gt; &gt; call, write an IO<br>
&gt; &gt; &gt; action yourself. try the difference between<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;putStrLn (hanoi ...)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; and<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;print (hanoi ...)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; to see what I mean.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Last, but not least, I would like to point out a<br>
&gt; &gt; &gt; different aproach to<br>
&gt; &gt; &gt; multiline output which is often used by Haskell<br>
&gt; &gt; &gt; programmers: The worker<br>
&gt; &gt; &gt; functions in this aproach produces a list of<br>
&gt; &gt; &gt; strings, which is joined<br>
&gt; &gt; &gt; together with newlines by the unlines function.<br>
&gt; In<br>
&gt; &gt; &gt; your case:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;hanoi_helper :: ... -&gt; [String]<br>
&gt; &gt; &gt; &nbsp; &nbsp; &nbsp;| ... = [&quot;Move &quot; ++ ...]<br>
&gt; &gt; &gt; &nbsp; &nbsp; &nbsp;| otherwise = hanoi_helper ... ++<br>
&gt; hanoi_helper<br>
&gt; &gt; &gt; ...<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;hanoi n = hanoi_helper &#39;a&#39; &#39;b&#39; &#39;c&#39; n<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; and in the interpreter one of these:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; hanoi 2 -- outputs a list<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; mapM_ putStrLn (hanoi 2) -- outputs each<br>
&gt; move<br>
&gt; &gt; &gt; in a new line<br>
&gt; &gt; &gt; &nbsp; &nbsp;&gt; putStrLn (unlines (hanoi 2)) -- same as<br>
&gt; &gt; &gt; previous line<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Tillmann<br>
&gt; &gt; &gt; _______________________________________________<br>
&gt; &gt; &gt; Haskell-Cafe mailing list<br>
&gt; &gt; &gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; &gt; &gt;<br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt; &gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Haskell-Cafe mailing list<br>
&gt; &gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; &gt;<br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt; &gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br>