给定由\ n分隔的文本输入文件时,此程序会产生我期望的输出:
import System.IO
main :: IO ()
main = do h <- openFile "test.txt" ReadMode
xs <- getlines h
sequence_ $ map putStrLn xs
getlines :: Handle -> IO [String]
getlines h = hGetContents h >>= return . lines
通过用withFile代替openFile并稍微重新排列
import System.IO
main :: IO ()
main = do xs <- withFile "test.txt" ReadMode getlines
sequence_ $ map putStrLn xs
getlines :: Handle -> IO [String]
getlines h = hGetContents h >>= return . lines
我设法没有任何输出。我很沮丧
编辑:不再难过:多亏了一个深思熟虑和发人深省的答案。我在文档中做了一些进一步的阅读,并了解到和File 可以理解为支架的部分应用。
我最终得到的是:
import System.IO
main :: IO ()
main = withFile "test.txt" ReadMode $ \h -> getlines h >>= mapM_ putStrLn
getlines :: Handle -> IO [String]
getlines h = lines `fmap` hGetContents h
最佳答案
该文件关闭太早。从documentation:
这意味着withFile
函数返回后,文件将立即关闭。
因为hGetContents
和 friend 很懒,所以在强制使用putStrLn
之前,它不会尝试读取文件,但是到那时,withFile
已经关闭了文件。
要解决此问题,请将整个内容传递给withFile
:
main = withFile "test.txt" ReadMode $ \handle -> do
xs <- getlines handle
sequence_ $ map putStrLn xs
之所以可行,是因为
withFile
在关闭文件之前就已经打印了。关于haskell - withFile与openFile,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9406463/