Your problem is actually one where using Haskell's "infinite" lists can make for an elegant solution. The idea is to generate an infinite list of repititions of the input string, then take exactly as many as we need, then decide how we're going to print that finite sublist:
printNTimes :: Int -> String -> IO ()
printNTimes n s = putStrLn . customShow . take n . repeat $ s
where
customShow [] = "[]"
customShow ss = concat ss
The standard Prelude
function, repeat
(not the same as the one you've defined yourself), takes a single exemplar of something and creates an infinite list of this thing by simply repeating it over and over "forever". So:
repeat "hello" = ["hello", "hello", "hello", ...] -- not valid Haskell
repeat 3 = [3, 3, 3, ...] -- not valid Haskell
Of course, we can never show or in any other fully concrete way realize an infinite list on a machine which after all has only finite memory. But this isn't a problem, since we'll only need the first n
elements of the list, and that is what take n
does in the function above. Note that when n <= 0
, take n
returns the empty list regardless of what it's applied to, in particuarl, take (-1) ["hello", "hello", ...] = []
.
Once we have the n
elements we're interested in, we can show them however we like, and that's just what customShow
does: if it sees an empty list, it prints "[]", otherwise it concatenates all the strings we've just taken from our list of repeats together into one long string and shows it in the usual way.
On a sidenote, it's good practice in Haskell to separate pure functions, such as the customShow . take n . repeat
part of printNTimes
, from impure IO
operations such as putStrLn
. In printNTimes
, the pure and the impure are combined by composition, but it would be better to write something like...
showNTimes :: Int -> String -> String
showNTimes n = customShow . take n . repeat
where
customShow [] = "[]"
customShow ss = concat ss
And then later, perhaps in your main
function, you'll have a sequence like this:
main :: IO ()
main = do
s <- getLine
...
putStrLn $ showNTimes 10 s
...
Good luck with your Haskelling! It's a beautiful language and rewarding to learn.