Indentation is significant in Haskell. Haskell uses indentation to group pieces of code together. This is similar to Python, but there are “false cognates” - similar code that is indented differently in the two languages. In Racket, grouping is done only by parentheses.
“All grouped expressions must be exactly aligned.”
Example 1a: good indentation
if x `mod` 3 == 0 &&
x `mod` 5 == 0 -- good. aligned with top x.
...
Example 1a: bad indentation
if x `mod` 3 == 0 &&
x `mod` 5 == 0 -- wrong. not aligned with top x
...
“Code which is part of some expression [must] be indented further than the beginning of that expression.
On one hand, this means that if you do not indent, you are not continuing a preceding expression. Example 2:
if x `mod` 3 == 0 &&
x `mod` 5 == 0
then -- wrong; needs to be indented further than the if
x
else -- wrong again
0
On the other hand, if you do indent, you may be continuing something you wrote previously.
How could this be an issue? If you write one function and then indent a later function, Haskell thinks you want the second function to be inside the first function (as in, a “sub-function”).
Example:
main = do
putStrLn $ helper 5
-- all this space does not change anything... --
answer x = 200 * x
helper x = answer x + 1
Notice how answer
is indented more than main
? That makes the answer
function live inside of main
… this will cause all sorts of
problems, but the first one is that helper
cannot see answer
because helper
cannot see anything inside of another function like
main
.
The source for all quotes in this article is the Haskell article on indentation. Other example issues came from observations in class.