What indentation is required for a case statement within a let statement?

前端 未结 2 1059
我在风中等你
我在风中等你 2020-11-27 22:54

Working in haskell, found odd behavior, stripped it down to bare bones

This Works

a :: Bool
a = case True of
    True -> True
    False -> Fals         


        
相关标签:
2条回答
  • 2020-11-27 23:16

    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.

    0 讨论(0)
  • 2020-11-27 23:24

    I don't have the exact wording from the spec, but this Wikibook page explains the issue quite clearly.

    The reason why it works like this is simple: to support binding multiple variables via a single let-group, such as:

    c = do
        let c' = …
            d  = …
            e  = …
        return c'
    

    Your True -> … and False -> … are mistakenly interpreted as additional variables to be bound.

    0 讨论(0)
提交回复
热议问题