我对 Haskell 还很陌生,我正在尝试简单地将文件读入字符串列表。我想要列表中每个元素占一行文件。但我遇到了一个我不明白的类型问题。这是我为我的函数编写的内容:
readAllTheLines hdl = (hGetLine hdl):(readAllTheLines hdl)
编译得很好。我原以为文件句柄需要与从 openFile
返回的文件句柄相同。我尝试通过执行以下操作来简单地显示上述函数中的列表:
displayFile path = show (readAllTheLines (openFile path ReadMode))
但是当我尝试编译它时,出现以下错误:
filefun.hs:5:43: Couldn't match expected type 'Handle' with actual type 'IO Handle' In the return type of a call of 'openFile' In the first argument of 'readAllTheLines', namely '(openFile path ReadMode)' In the first argument of 'show', namely '(readAllTheLines (openFile path ReadMode))'
所以看起来 openFile 返回一个 IO Handle
,但是 hGetLine
需要一个普通的旧 Handle
。我是否误解了这两个功能的用途?它们不是打算一起使用吗?或者我只是缺少一 block ?
最佳答案
使用 readFile
和 lines
以获得更好的替代方案。
readLines :: FilePath -> IO [String]
readLines = fmap lines . readFile
回到您的解决方案openFile
返回IO Handle
,因此您必须运行操作才能获取Handle
。在从中读取内容之前,您还必须检查 Handle
是否位于 eof。使用上面的解决方案就简单多了。
import System.IO
readAllTheLines :: Handle -> IO [String]
readAllTheLines hndl = do
eof <- hIsEOF hndl
notEnded eof
where notEnded False = do
line <- hGetLine hndl
rest <- readAllTheLines hndl
return (line:rest)
notEnded True = return []
displayFile :: FilePath -> IO [String]
displayFile path = do
hndl <- openFile path ReadMode
readAllTheLines hndl
关于haskell - 将文件读入字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18710999/