programnub
programnub

Reputation: 85

Printing a String in a pyramid shape in Haskell

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

Answers (3)

Nima Mousavi
Nima Mousavi

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

chi
chi

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

jamshidh
jamshidh

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

Related Questions