
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
but got stuck on outputting newlines as part of
Benjamin L. Russell wrote: 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@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe