Reputation: 63
I am trying to write a function in haskell that would take an integer and return a concatenated (number of times the input) string
For Instance,
Input: 3
Output: hi1\nhi2\nhi3
main = do
let str = func 2 ""
putStrLn str
func :: Int -> String -> String
func i str = do
if i>(-1)
then do
str ++ "hi" ++ (show i)
func (i-1) str
else str
Thanking you!
Upvotes: 1
Views: 1847
Reputation: 11940
I wonder if 'logarithmic' solution is faster:
main = putStrLn $mul 7 "Hi"
mul :: Int -> String -> String
mul 0 _ = ""
mul 1 s = s
mul _ "" = ""
mul n s = let
(q, r) = n `quotRem` 2
s' = mul q s
in (if r == 1 then s else "") ++ s' ++ s'
Upvotes: 2
Reputation: 135257
This is a much more idiomatic solution than using if-else
a function that would take an integer and return a concatenated (number of times the input) string
func :: Int -> String -> String
func 0 s = ""
func n s = s ++ func (n - 1) s
main = putStrLn (func 3 "hi")
Output
hihihi
Upvotes: 3
Reputation: 6463
The easiest way to make your code "work" (I'll explain the double quotes later) is to call func
with the concatenated string as a parameter directly, without intermediate steps:
func :: Int -> String -> String
func i str = do
if i > (-1)
then func (i-1) (str ++ "hi" ++ (show i) ++ "\n")
else str
I also added the newline character to the output, which means that the last character of the result will be a new line. Therefore it is better to write
let str = func 2 ""
putStr str
That way you'll avoid an extra new line at the end.
I wrote "works" in double quotes in the first sentence, because my code prints
hi2
hi1
hi0
You need to modify func
so that the lines are printed in reverse order. Hint: you can store the lines in a list and reverse the list at the end.
P.S. I'm not sure whether zero should be a valid suffix. If not, then you have to change the condition in your if
statement.
Upvotes: 1