【问题标题】:Haskell Read Integers from a file to a listHaskell 从文件读取整数到列表
【发布时间】:2017-09-11 01:46:17
【问题描述】:

我有一个包含一行的简单文本文件:

6 195 265 750 265 750 196

我有一个函数:

executeList :: Integer -> [Integer] -> [String]
executeList n x = [reverseAndAdd n i | i <- x]

这需要一个整数,整数列表并返回一个字符串数组。

我想要做的是将该文本文件读取到 [Integer] 列表并将其传递给 executeList 函数。 这是我的代码:

main = do  
    let list = []
    handle <- openFile "data.txt" ReadMode
    contents <- hGetContents handle
    let singlewords = words contents
        list = f singlewords
    print list
    hClose handle   
f :: [String] -> [Integer]
f = map read

我在这里找到了它: Haskell file reading

当我运行“main”时,我得到以下输出: [6,195,265,750,265,750,196]

但是当我尝试像这样将它传递给executeList时:

let list = main
executeList 0 list

我收到此错误:

<interactive>:103:15: error:
* Couldn't match expected type `[Integer]' with actual type `IO ()'
* In the second argument of `executeList', namely `list'
  In the expression: executeList 0 list
  In an equation for `it': it = executeList 0 list

如果我检查该列表的类型,我会得到:

list :: IO()

我在互联网上查找如何将 IO() 转换为 [Integer] 但没有发现任何有用的信息。也许有人可以告诉我进行这种转换的方法?

【问题讨论】:

  • 在你的主目录中使用print list 而不是print (executeList 0 list)?请注意,没有(安全)函数IO a -&gt; a
  • 谢谢!!!还有一个问题。是否可以将此列表写入同一函数中的其他文件?我尝试添加类似:outh
  • 但得到:输入“
  • @motleycrue 无需手动处理句柄,只需使用{read,write}File 的高级函数即可。对于您的第二个问题,请考虑writeFile "results.txt" (unwords (executeList 0 list))
  • 谢谢你们。祝你有美好的一天,伙计们:)

标签: haskell io


【解决方案1】:

简短的回答是您不能将IO() 转换为[Integer]

您似乎误解了IO monad。大多数函数返回一个值。返回类型为IO a 的函数会返回一个I/O 操作,该操作在返回a 类型的值之前执行某种类型的I/O。在您的情况下,IO () 是一个 I/O 操作,它将返回 () 这只是一个空元组。当您编写这样的控制台程序来读取数据然后打印出一些结果时,您通常会遵循以下模式:

  1. 从文件或命令行读取输入
  2. 将数据传递给函数进行计算
  3. 打印结果

您的整个程序最终将存在于 IO monad 中。 do 是一个符号,它是绑定运算符 &gt;&gt;= 的语法糖。该运算符允许我们将单子计算链接在一起。您代码中的 &lt;- 从 monad(在您的情况下为 IO 操作)中提取一个值并将其存储在一个变量中。让我们看一下hGetContents 的类型签名。从 GHCI 中我们可以了解到这个函数的类型是 hGetContents :: Handle -&gt; IO String 它接受 Handle 并返回一个返回字符串的 I/O 操作。当您调用contents &lt;- hGetContents handle 时,程序会使用您指定的文件句柄调用hGetContents,然后从返回的IO 操作中提取一个字符串并将该字符串存储在变量内容中。所以现在你已经阅读了输入。将数字转换为实际整数类型后,下一步是调用您的函数,即简单调用 let data = executeList 0 list 从那里您可以使用 print data 输出数据。重要的是要记住,你一直都在 IO monad 中。最后你的整个 main 函数应该是这样的:

main = do
    handle <- openFile "data.txt" ReadMode
    contents <- hGetContents handle
    let singlewords = words contents
        list = f singlewords
        data = executeList 0 list
    print data
    hClose handle   

f :: [String] -> [Integer]
f = map read

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多