Skip to content


When you write a definition in your code, like:

flag = True -- (1)!
  1. flag isn't a keyword, it's just a normal variable name.


swap (a, b) = (b, a)

you cannot later write in the same codebase:

flag = False


swap (a, b) = (a, b)

This is because all Haskell values (including functions) are immutable. To write a = b is simply to state that a is a name for b, and that wherever you see a in the code, it can be replaced by b.

For example, given the definition swap (a, b) = (b, a), whenever you see swap (a, b) in your code, it can be replaced by (b, a).

Loops and mutation

In Python you could write:

x = 0
for i in range(10):
    x += i

This imperative approach isn't usually the natural one in a functional language.


There are fairly simple ways to write code like this, e.g.:

import Control.Monad (forM)
import Control.Monad.State (execState, modify)

loop = flip execState 0 $ forM [0..9] $ \i -> -- (1)!
    modify (+i)
  1. Here, forM and modify are just regular functions, not built-in control-flow operators.

However, there's often a simpler solution that avoids thinking about loops and state altogether.

Instead, you could write:

x = sum [0..9]

See this section for how this kind of approach scales to more complex situations.

Last update: January 12, 2023
Created: January 7, 2023