【问题标题】:Reading a file into an array of strings将文件读入字符串数组
【发布时间】:2013-09-10 04:58:16
【问题描述】:

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

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

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

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

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

filefun.hs:5:43: 无法将预期类型“句柄”与实际类型“IO 句柄”匹配 在“openFile”调用的返回类型中 在“readAllTheLines”的第一个参数中,即 '(打开文件路径 ReadMode)' 在'show'的第一个参数中,即 '(readAllTheLines (openFile path ReadMode))'

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

【问题讨论】:

  • 您是否已经看过像Learn you a Haskell 这样的优秀Haskell 教程?它关于Input and Output 的章节将更容易理解一些值和IO 中的值之间的区别。
  • 今晚我刚刚找到了那个特别的教程。我一直在阅读 Haskell wikibook,但我发现它在后面的章节中变得令人困惑。谢谢指点!

标签: haskell


【解决方案1】:

使用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 

【讨论】:

  • 谢谢!我需要阅读linesreadFile,但我想我掌握了基本概念。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
相关资源
最近更新 更多