我有一行简单的文本文件:
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],但没有发现任何有用的东西。也许有人可以告诉我进行转换的方法?
答案 0 :(得分:1)
简短的回答是,您无法将IO()
转换为[Integer]
。
好像你误解了IO monad。大多数函数返回一个值。返回类型为IO a
的函数返回一个I / O操作,该操作在返回类型a
的值之前执行某种排序I / O.在您的情况下,IO ()
是一个I / O操作,它将返回()
,这只是一个空元组。当您编写这样的控制台程序来读入数据然后打印出一些结果时,您通常会遵循以下模式:
你的整个程序最终将生活在IO monad中。 do
是一个符号,它是绑定运算符>>=
的语法糖。该运算符允许我们将monadic计算链接在一起。代码中的<-
从monad中提取值(在您的情况下是IO操作)并将其存储在变量中。让我们看一下hGetContents
的类型签名。从GHCI我们可以知道这个函数的类型为hGetContents :: Handle -> IO String
它需要Handle
并返回一个返回字符串的I / O操作。当您调用contents <- hGetContents handle
时,程序使用您指定的文件句柄调用hGetContents
,然后从返回的IO操作中提取字符串,并将该字符串存储在变量内容中。所以现在你已经阅读了输入。在将数字转换为实际整数类型之后,下一步是调用您的函数,即简单调用let data = executeList 0 list
从那里您可以使用print data
输出数据。重要的是要记住你在IO monad中的整个时间。最后,您的整个主要功能应如下所示:
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