An experienced programmer will be thinking about a for loop or a while loop. They will then be surprised to learn that there is no such thing in Haskell, not even something closely resembling such. As they say in the "Wizard of Oz", we aren't in Kansas anymore.
Hold on to your hat. I am going to throw a bunch of Haskell at you without properly explaining it. After this page, I will try to do better at controlling myself -- for now just view it as a taste of things to come and don't feel bad about being confused.
One way to do a loop is to use recursion. Haskell does have some library function to repeat things, but if you dig deep you will find they are implemented using recursion. Here you go:
n = 7
put 0 = return ()
put x = do
putStrLn "Hello World!"
put (x-1)
main = put n
We are introducing a lot here, but you can probably make smart guesses
about what is going on.
We set a variable (at least we call it a variable for now) to the value "7" which is how many times we want to repeat the message. Then on the last line the main function is defined to be the put function called with the argument n.
Rather than testing for zero to end the recursion, we do things a different way. We give a definition of the put function to match when it gets the argument 0. This function just becomes "return ()" which is actually deep magic, but it ultimately does nothing and produces the value () which is the nil value.
When "put" has a non-zero argument, we use "do notation" to give it a definition that looks like two statments one after the other. Do notation is also deep magic that we will explain later. For now just think of it as a way to introduce a short bit of code that runs in sequence.
The main point of all this is to give you a taste of how different things are in the world of Haskell. There are other ways to repeat things. The most likely Haskell idiom might be this:
import Control.Monad (forM_)
n = 7
main = forM_ [1..n] $ \_ -> do
putStrLn "Hello World!"
Here we import the forM_ function from the Control.Monad module.
The expression [1..n] is actually a list (of numbers 1 through n). The forM_ function would accept any list here, and crank through it. We discard the list element using \_ -- if we wanted to use it, we could replace this with \i and then use the variable "i" in the loop, as in the following:
main = forM_ [1..4] $ \i -> putStrLn $ show iBy the way, the backslash is introducing what is called a "lambda expression" which is essentially a nameless function. We will focus on this later.
What are all the dollar signs for you should be asking. We will get to that too.
Tom's software pages / tom@mmto.org