给定由\ 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/

10-11 20:31