缩进在这里扮演什么角色?为什么一个缩进不起作用?

Ale*_*ong 4 haskell indentation

这是RWH书中的示例程序.我想知道为什么第一个工作很好但第二个甚至不能编译?唯一的区别是第一个使用2个标签,where mainWith func = do而第二个仅使用1.不确定这意味着什么区别?为什么第二个无法编译?还有为什么do construct可以空?

非常感谢,Alex

-- Real World Haskell Sample Code Chapter 4:
-- http://book.realworldhaskell.org/read/functional-programming.html

import System.Environment (getArgs)

interactWith func input output = do
    s <- readFile input
    writeFile output (func s)

main = mainWith myFunction
    where mainWith func = do
            args <- getArgs
            case args of 
                [fin, fout] -> do
                    interactWith func fin fout
                _ -> putStrLn "error: exactly two arguments needed"

myFunction = id


-- The following code has a compilation error
-- % ghc --make interactWith.hs
-- [1 of 1] Compiling Main             ( interactWith.hs, interactWith.o )
-- 
-- interactWith.hs:8:26: Empty 'do' construct


import System.Environment (getArgs)

interactWith func input output = do
    s <- readFile input
    writeFile output (func s)

main = mainWith myFunction
    where mainWith func = do
        args <- getArgs
        case args of 
            [fin, fout] -> do
                interactWith func fin fout
            _ -> putStrLn "error: exactly two arguments needed"

myFunction = id
Run Code Online (Sandbox Code Playgroud)

sth*_*sth 7

mainWith函数的定义缩进到第10列:

    where mainWith func = do
          ^
Run Code Online (Sandbox Code Playgroud)

do在此行中开始的块的内容仅缩进到第8列:

        args <- getArgs
        case args of 
            ...
        ^
Run Code Online (Sandbox Code Playgroud)

如果增加do块内容的缩进也至少缩进到第10列,则正确解析代码.对于当前缩进,应该属于该do块的行被视为该where子句的一部分,而不是该mainWith函数.