开发者

What role does the indentation play here? and Why one indent doesn't work?

开发者 https://www.devze.com 2023-01-07 05:07 出处:网络
Here is a sample program from RWH book.I\'m wondering why the first works great but the second can\'t even compile? The only difference is the first one uses 2 tabs after where mainWith func = do wher

Here is a sample program from RWH book. I'm wondering why the first works great but the second can't even compile? The only difference is the first one uses 2 tabs after where mainWith func = do whereas the second uses only 1. Not sure what difference does that mean? Why the second fails to compile? And also why do construct can be empty?

Thanks a lot, A开发者_开发知识库lex

-- 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


The definition of the mainWith function is indented to column 10:

    where mainWith func = do
          ^

The contents of the do block started in this line are only indented to column 8:

        args <- getArgs
        case args of 
            ...
        ^

If you increase the indentation of the contents of the do block to be also indented at least to column 10, the code is parsed correctly. With the current indentation the lines that should belong to the do block are seen to be part of the where clause, but not the mainWith function.


The do-block can not be empty, that's why you get the error. When using only one tab args <- getArgs is seen as part of the where-block, not the do-block, so the do-block is empty and you get an error.

The thing is that unless you use {} and ; to explicitly state which block goes from where to where, haskell relies on indendation. And since you indented your line only by one level, it was seen as part of the where-block.

0

精彩评论

暂无评论...
验证码 换一张
取 消