[Haskell-cafe] Re: Embedding newlines into a string?

Benjamin L. Russell dekudekuplex at yahoo.com
Mon Apr 14 04:42:42 EDT 2008


Ok; much better.  Here's my new type signature and
definition:

hanoi.hs:
hanoi :: Int -> IO ()
hanoi n = mapM_ putStrLn (hanoi_helper 'a' 'b' 'c' n)
          
hanoi_helper :: Char -> Char -> Char -> Int ->
[String]
hanoi_helper source using dest n
    | n == 1 = ["Move " ++ show source ++ " to " ++
show dest ++ "."]
    | otherwise = hanoi_helper source dest using (n-1)

                  ++ hanoi_helper source using dest 1
                         ++ hanoi_helper using source
dest (n-1)

Then in WinHugs (Version Sep 2006):

Hugs> :load hanoi.hs
Main> hanoi 2
Move 'a' to 'b'.
Move 'a' to 'c'.
Move 'b' to 'c'.

Great!

One minor question:  I tried out both of your
following suggestions:

>    > mapM_ putStrLn (hanoi 2) -- outputs each move
> in a new line
>    > putStrLn (unlines (hanoi 2)) -- same as
> previous line

and discovered that putStrLn with unlines (the lower
option) in fact generates one extra blank line at the
end.  Just curious as to why....

Benjamin L. Russell

--- Tillmann Rendel <rendel at daimi.au.dk> wrote:

> Benjamin L. Russell wrote:
> > but got stuck on outputting newlines as part of
> the string;
> 
> quoting is done by the show function in Haskell, so
> you have to take 
> care to avoid calling show. your code calls show at
> two positions:
> (1) when you insert the newline into the string
> (2) when you output the string
> 
> with respect to (1):
> 
> you use (show '\n') to create a newline-only string,
> which produces a 
> machine-readable (!) textual representation of '\n'.
> try the difference 
> between
> 
>    > '\n'
> 
> and
> 
>    > show '\n'
> 
> to see what I mean. instead of using (show '\n'),
> you should simply use 
> "\n" to encode the string of length 1 containing a
> newline character.
> 
> with respect to (2):
> 
> the type of your top-level expression is String,
> which is automatically 
> print'ed by the interpreter. but print x = putStrLn
> (show x), so there 
> is another call to show at this point. to avoid this
> call, write an IO 
> action yourself. try the difference between
> 
>    putStrLn (hanoi ...)
> 
> and
> 
>    print (hanoi ...)
> 
> to see what I mean.
> 
> Last, but not least, I would like to point out a
> different aproach to 
> multiline output which is often used by Haskell
> programmers: The worker 
> functions in this aproach produces a list of
> strings, which is joined 
> together with newlines by the unlines function. In
> your case:
> 
>    hanoi_helper :: ... -> [String]
>      | ... = ["Move " ++ ...]
>      | otherwise = hanoi_helper ... ++ hanoi_helper
> ...
> 
>    hanoi n = hanoi_helper 'a' 'b' 'c' n
> 
> and in the interpreter one of these:
> 
>    > hanoi 2 -- outputs a list
>    > mapM_ putStrLn (hanoi 2) -- outputs each move
> in a new line
>    > putStrLn (unlines (hanoi 2)) -- same as
> previous line
> 
> Tillmann
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 



More information about the Haskell-Cafe mailing list