3

我对 Haskell 很陌生,并且试图简单地将文件读入字符串列表。我希望列表中的每个元素都有一行文件。但是我遇到了一个我不明白的类型问题。这是我为我的函数编写的内容:

readAllTheLines hdl = (hGetLine hdl):(readAllTheLines hdl)

这编译得很好。我曾认为文件句柄需要与从openFile. 我试图通过执行以下操作来简单地显示上述函数的列表:

displayFile path = show (readAllTheLines (openFile path ReadMode))

但是当我尝试编译它时,我收到以下错误:

filefun.hs:5:43: 无法将预期类型 'Handle' 与实际类型 'IO Handle' 匹配 在 'openFile' 调用的返回类型中 在 'readAllTheLines' 的第一个参数中,即 '(openFile path ReadMode )' 在'show'的第一个参数中,即'(readAllTheLines(openFile path ReadMode))'

所以看起来 openFile 返回一个IO Handle,但hGetLine需要一个普通的 old Handle。我是否误解了这两个功能的使用?它们不打算一起使用吗?或者只是我缺少一块?

4

1 回答 1

6

使用readFilelines作为更好的选择。

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 
于 2013-09-10T05:06:22.463 回答