Q:

Repeatedly append to string haskell

Hi i'm new to haskell and am unsure how to approach it. I have the following code so far
ask :: String -> IO ()
ask prompt =
  do
  putStrLn prompt
  line <- getLine
  if line == ""
    then ask "please try again"
    else putStrLn ("you said: " ++ reverse line)

main :: IO ()
main =
  do
  ask "please say something"

i'm trying to make it so that when someone presses enter without typing anything, the repeated prompt will have an extra “!” at the end. So every time it repeats it adds an additional "!"
Example Output:
please say something
please try again!
please try again!!
please try again!!!

A:

You can add a counter to your method, like:
ask :: String -> IO ()
ask = ask' 1

ask' :: Int -> String -> IO ()
ask' n prompt = do
  putStrLn prompt
  line <- getLine
  if null line
    then ask' (n+1) ("please try again" ++ replicate n '!')
    else putStrLn ("you said: " ++ reverse line)

A:

Instead of passing one prompt to ask, pass all your prompts, in the form of an infinite list generated by iterate:
ask :: [String] -> IO ()
ask (p:ps) =
  do
  putStrLn p
  line <- getLine
  if line == ""
    then ask ps
    else putStrLn ("you said: " ++ reverse line)

main :: IO ()
main =
  do
  ask ("please say something" : iterate (++"!") "please try again")

Each call to ask prints the first prompt in its input and passes the rest on to the recursive call.

