当给定由 \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
我根本没有得到任何输出。我很困惑。
编辑:不再被难住了:感谢所有人的深思熟虑和发人深省的答案。我在文档中做了更多阅读并了解到withFile可以理解为部分应用bracket.
这就是我最终得到的结果:
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
该文件关闭得太早。来自文档 http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO.html#v:withFile:
手柄将是从 withFile 退出时关闭
这意味着文件将在以下时间后立即关闭withFile
函数返回。
Because hGetContents
而且朋友们很懒,它不会尝试读取文件,除非它被强制putStrLn
,但到那时,withFile
本来就已经关闭了文件。
为了解决问题,将整个事情传递给withFile
:
main = withFile "test.txt" ReadMode $ \handle -> do
xs <- getlines handle
sequence_ $ map putStrLn xs
这是有效的,因为到时候withFile
抽出时间关闭文件,您可能已经打印了它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)