[英]'do' construct in Haskell
我正在嘗試學習Haskell,並想編寫一個小程序,將文件的內容打印到屏幕上。 將其加載到GHCi中時,出現以下錯誤:
“ do”構造中的最后一條語句必須是表達式
我知道這個問題已經在這里被問到了: Haskell —“'do'構造中的最后一個語句必須是一個表達式” 。
即使我的代碼非常相似,我仍然無法找出問題所在。 如果有人可以向我指出問題,我將非常感激。
module Main (main) where
import System.IO
import System(getArgs)
main :: IO()
main = do
args <- getArgs
inh <- openFile $ ReadMode head args
printFile inh
hClose inh
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
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
)到此結束。
有一些問題。 首先,將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
。 如果您想更詳細地說明版本不正確的原因/方式或錯誤的含義,請告訴我,我將進行編輯。
你這樣寫:
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
您始終可以將顯式括號與{ ; }
{ ; }
永遠不必擔心這個空白愚蠢。
printFile :: Handle -> IO ()
printFile handle = do {
end <- hIsEOF handle ;
if end
then return ()
else do { line <- hGetLine handle ;
putStrLn line ;
printFile handle }}
本來會很好(例如,不會導致錯誤)。
在Haskell中,通過特殊的“ do
”語言來處理I / O。 應該接受它。 它實際上是通過monad實現的是實現細節。
需要說明的是:我認為大括號不是更好,我認為它們應該與優美而一致的縮進一起使用。 花括號為我們提供了有關代碼結構的直觀,直觀的線索。 當然,在大多數情況下,瘋狂的縮進毫無意義。 而且,花括號為我們提供了工作代碼的保證,並使我們免於對空白事故的毫無意義的擔心。 他們消除了這種脆性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.