The basic indentation rules are actually quite simple:
- after the keywords which start a block (
where
,let
,do
,case .. of
) note down the column where the next word starts (which might be in the next line) - lines indented exactly as that are new entries in the block
- lines indented more than that continue the previous entry
- a line indented less than that ends the block right before that line
- in nested blocks, apply the rules to the outermost block, first
Tricky example:
1 + case x of
A -> 45 -- note where "A" starts
B -> 10 -- same indentation: another case branch
+ 2 -- more indented, so it's "10+2"
+ 10 -- less indented, so it's "1+(case ...)+10"
In your case,
let b' = case True of
True -> True
False -> False
we have two nested blocks, one for let
and one for case..of
. The let
blocks uses the column of b'
. The case..of
block tries to reuse the same column, but we need to apply the rules the the outermost block, first. So the True -> ...
line is actually a new entry of the let
block. This triggers a parsing error.