Reputation: 85
I am really new with Haskell. I am trying to improve my code by printing "Hi" in this order. For example n = 4, the output is:
Hi
Hi Hi
Hi Hi Hi
Hi Hi Hi Hi
My current code is:
printHi :: Integer -> String
printHi n = concat["Hi" | n <- [0..n-1]]
and its output is:
Hi Hi Hi Hi
Any tips on how I will be able to perform this task?
Upvotes: 3
Views: 4313
Reputation: 1661
Sounds to me like you want to use scanl
. scanl
is like a fold except that it saves the intermediate results. If you have a list like ["Hi", "Hi", "Hi", "Hi"]
, then fold
with (++)
will produce a string like "HiHiHiHi"
. With scanl
the intermediate results will also be saved: ["", "Hi", "HiHi" ....
etc.
Now, if I were to shamelessly take your code and modify it a little bit the result might be this:
printHi :: Integer -> [String]
printHi n = scanl (++) "" ["Hi " | n <- [0..n-1]]
I added a space to "Hi "
to make it look a little bit more like in
your question. So the result will be a list that looks like this:
["", "Hi ", "Hi Hi ", "Hi Hi Hi ", "Hi Hi Hi Hi "]
If you use the function "unlines" on the resulting list it will produce
the desired out put as stated in the question and of course the empty string at the start of the list can be removed with tail
if you desire to do so.
Upvotes: 0
Reputation: 116174
There are two possible approaches.
One is to build a large string, comprising all the "Hi"
parts and the needed newlines. After that, printing the string suffices. (This is what jamshidh did above).
Alternatively, one can use a more "imperative" approach and use a loop. For example,
import Control.Monad
foo :: IO ()
foo = forM_ [1..100] $ \i ->
putStrLn ("The current value of i is" ++ show i)
will print the numbers from 1
to 100
, each with a short message. Adapting this to your case is left as an exercise.
(flip traverse_
can also be used instead of forM_
)
The first style is probably more flexible, in that the crafted string can be reused in non-IO contexts. However, if we are sure we will never need that string for other purposes than to print it, the second approach will suffice.
Upvotes: 3
Reputation: 12070
Here is a way to print "hi" 4 times....
putStrLn $ unwords $ replicate 4 "hi"
Here is a way to print the triangle pattern you showed above
putStrLn $ unlines $ map (unwords . flip replicate "hi") [1..4]
Upvotes: 3