Version 3 (modified by john@…, 9 years ago) (diff)


The do-notation and if-then-else

This page concerns the possibility of tweaking the layout rules to avoid a common pitfall when if-then-else is used with the do-notation. It only documents a problem: no specific solution is proposed. The issue is somewhat related to NondecreasingIndentation. Strictly speaking, the issue is not tied to the do-notation, but that is where it (almost?) always shows up.

Brief Explanation

I have lost count of how many times people (including very experienced programmers) have approached me wondering why on earth code like the following fails to parse:

foo :: Monad m => Bool -> m Int
foo x = do
    if x then
        return 1
        return 2

When I explain that they have to indent the else at least one more step, they invariably stare at me in disbelief and vow to henceforth stay far away from languages where layout has semantic significance. It can actually be somewhat embarassing, and it certainly can put beginners off.

Might it be possible to handle then and else specially to avoid this problem? At least in the context of do? Or might it be possible to treat if as something that opens a kind of explicit layout context (which would prevent the insertion of a closing }) that is closed by a matching else?


This has been implemented in jhc by changing a single line in the parser, an equivalant change in the report should have the same effect.

  | 'if' exp 'then' exp 'else' exp { HsIf $2 $4 $6 }
  | 'if' exp optsemi 'then' exp optsemi 'else' exp { HsIf $2 $5 $8 }

so far, it has not caused any problems.



  • Would address a layout issue that manifestly trips up a lot of people and which at least one experienced Haskell programmer (me!) finds very annoying.


  • No concrete proposal yet
  • Not implemented in any system to my knowledge