1
4

4 回答 4

5

你的缩进被打破了。这些更好:

printFile :: Handle -> IO ()
printFile handle = do
    end <- hIsEOF handle
    if end
        then return ()
        else do line <- hGetLine handle
                putStrLn line
                printFile handle

printFile :: Handle -> IO ()
printFile handle = do
    end <- hIsEOF handle
    if end
        then return ()
        else do
            line <- hGetLine handle
            putStrLn line
            printFile handle

通过if比 进一步缩进end <- hIsEof handle,它实际上是一个行继续,而不是do. putStrLn line类似地,缩进比缩进少的事实line <- hGetLine handle意味着do(内部else)在此处结束。

于 2010-12-22T20:50:26.743 回答
4

有几个问题。首先,if缩进太远 -end <- ...被认为是do. 不缩进...

下一个问题出现了。相同的错误消息,仅在第 18 行。这一次,第 19 行和第 20 行的缩进不够深(它们没有被解析为 的一部分do)。缩进(无论如何看起来更好,因为它现在都排好了)...下一个错误消息。好消息是,这一次不是缩进错误,修复也很简单。

test.hs:9:22:
    Couldn't match expected type `([a] -> a) -> [String] -> FilePath'
           against inferred type `IOMode'
    In the second argument of `($)', namely `ReadMode head args'
    In a stmt of a 'do' expression:
        inh <- openFile $ ReadMode head args
    In the expression:
        do { args <- getArgs;
             inh <- openFile $ ReadMode head args;
             printFile inh;
             hClose inh }

修复是inh <- openFile (head args) ReadMode. 如果您想更详细地解释为什么/如何您的版本不正确,或者错误意味着什么,请告诉我,我会进行编辑。

于 2010-12-22T20:56:06.900 回答
1

你写了这个:

main :: IO()
main = do
    args <- getArgs
    inh <- openFile $ ReadMode head args
    printFile inh
    hClose inh

但它可能像这样更好:

main :: IO()
main = do
    args <- getArgs
    withFile (head args) ReadMode printFile
于 2010-12-23T04:28:18.723 回答
1

您始终可以使用显式括号,{ ; }而不必担心这种空白愚蠢。

printFile :: Handle -> IO ()
printFile handle = do {
    end <- hIsEOF handle ;
        if end
            then return ()
            else do { line <- hGetLine handle ;
                putStrLn line ;
                printFile handle }}

本来完全没问题(如,不会导致错误)。

do在 Haskell 中,I/O 是通过特殊的 " " 语言处理的。它应该被接受。它实际上是通过 monads 实现的,这是一个实现细节。

澄清一下:我不认为大括号更好,我认为它们应该与一个漂亮且一致的缩进一起使用。大括号为我们提供了关于代码结构的良好且直接的视觉线索。大多数时候,狂野的缩进当然是一种毫无意义的干扰。而且,大括号为我们的工作代码提供了保证,并让我们摆脱了空白事故的无意义担心。他们消除了这种脆弱性。

于 2018-06-15T08:12:12.173 回答