[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