How do you increment a variable in a functional programming language?
For example, I want to do:
main :: IO () main = do let i = 0 i = i + 1 print i
Expected output:
1
The most simple way to increment/decrement a variable is by using the + and - operators. This method allows you increment/decrement the variable by any value you want.
A program can increment by 1 the value of a variable called c using the increment operator, ++, rather than the expression c=c+1 or c+=1. An increment or decrement operator that is prefixed to (placed before) a variable is referred to as the prefix increment or prefix decrement operator, respectively.
Increment() Function It takes a variable and increments (changes) its value, and also returns this value. The increment can be a positive or negative number. Note: The Increment() function changes the value of its first argument.
x++ (post-increment) means "remember the original value, then increment the variable; the value of the expression is the original value"
Simple way is to introduce shadowing of a variable name:
main :: IO () -- another way, simpler, specific to monads: main = do main = do let i = 0 let i = 0 let j = i i <- return (i+1) let i = j+1 print i print i -- because monadic bind is non-recursive
Prints 1
.
Just writing let i = i+1
doesn't work because let
in Haskell makes recursive definitions — it is actually Scheme's letrec
. The i
in the right-hand side of let i = i+1
refers to the i
in its left hand side — not to the upper level i
as might be intended. So we break that equation up by introducing another variable, j
.
Another, simpler way is to use monadic bind, <-
in the do
-notation. This is possible because monadic bind is not recursive.
In both cases we introduce new variable under the same name, thus "shadowing" the old entity, i.e. making it no longer accessible.
One thing to understand here is that functional programming with pure — immutable — values (like we have in Haskell) forces us to make time explicit in our code.
In imperative setting time is implicit. We "change" our vars — but any change is sequential. We can never change what that var was a moment ago — only what it will be from now on.
In pure functional programming this is just made explicit. One of the simplest forms this can take is with using lists of values as records of sequential change in imperative programming. Even simpler is to use different variables altogether to represent different values of an entity at different points in time (cf. single assignment and static single assignment form, or SSA).
So instead of "changing" something that can't really be changed anyway, we make an augmented copy of it, and pass that around, using it in place of the old thing.
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