I'm curious about implementing a loop in Haskell. How can I do something similar in Haskell (pseudo-code):
var i = 0
for (int i1 = 0; i1 < 10; i1++) {
println(i1)
i += 2
}
println(i)
In functional terms what you are doing is folding over a list of integers so that for each integer you print the element and increase an accumulator by 2. Since we are printing something (i.e. doing I/O) we need to fold in a monad but otherwise it's just your standard left-fold.
foldM (\i i1 -> print i1 >> return (i + 2)) 0 [0..9] >>= print
We fold with a lambda function that uses the same variable names as your code. I.e. i1 is the current element and i is the accumulator.
The next parameter is the initial value for the accumulator which corresponds to i = 0 in your code.
The final parameter is the (inclusive on both ends) list of numbers we fold over.
The >>= (bind operator) pipes the result of the fold (i.e. the final value of the accumulator i) to the print function.
EDIT: This is assuming that you meant to write
var i = 0
for (int i1 = 0; i1 < 10; i1++) {
println(i1)
i += 2
}
println(i)
instead of incrementing just i in both the for-clause and loop body.
Going by the two assumptions that
(the same assumption shang made) that you want to print out
0
1
2
3
4
5
6
7
8
9
20
I would in Haskell write
do
let xs = [0..9]
mapM_ print xs
print (length xs * 2)
You see how the original computation got split up into three separate (and independent!) computations.
i1 into a list. We know the bounds are 0 and 9 inclusive, so the loop variable can be represented by the list [0..9].i" from what we know about the list, and then print it as well.The third computation is especially interesting, because it highlights the difference between traditional imperative programming and Haskell, which is a lot about declarative programming.
Adding two to a number every iteration of a list is the same thing as taking the length of the list and multiplying it by two. The big difference, in my eyes, is that I can read i = length xs * 2 and understand what it means in the blink of an eye. Counting i up every iteration of a loop, however, takes some thinking to understand what it really means.
The fact that all three sub-computations are independent means they are a lot easier to test – you can test them one at a time and if they work individually, they will work together as well!
If you meant "similar" in the sense of "similar-looking code", refer to any of the STRef/IORef answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With