如何使用 Haskell 的 readFile 函数读取多个文件
How to use Haskell's readFile function for multiple files
我对IO有点了解。我知道您可以使用 readFile
来获取文件的内容。例如像这样:
main = do
let inputFilePath = "C:\Haskell\myawesomeprogram\files\a.txt"
content <- readFile inputFilePath
print content
调用程序:
> runghc myawesomeprogram
"AAA"
太棒了,太棒了!现在我想从多个文件中读取内容。
我试过这样的事情:
files = ["C:\Haskell\myawesomeprogram\files\a.txt", "C:\Haskell\myawesomeprogram\files\b.txt","C:\Haskell\myawesomeprogram\files\c.txt"]
main :: IO ()
main = do
filesContent <- readFiles files
print filesContent
readFiles (x:xs) = do
content <- readFile x
content : readFiles xs
这会给我以下错误信息:
myawesomeprogram.hs:6:21: error:
* Couldn't match type `[]' with `IO'
Expected type: IO String
Actual type: [String]
* In a stmt of a 'do' block: filesContent <- readFiles files
In the expression:
do filesContent <- readFiles files
print filesContent
In an equation for `main':
main
= do filesContent <- readFiles files
print filesContent
|
6 | filesContent <- readFiles files
| ^^^^^^^^^^^^^^^
myawesomeprogram.hs:9:1: error:
Couldn't match type `IO' with `[]'
Expected type: [FilePath] -> [String]
Actual type: [FilePath] -> IO String
|
9 | readFiles (x:xs) = do
| ^^^^^^^^^^^^^^^^^^^^^^^...
myawesomeprogram.hs:11:5: error:
* Couldn't match type `[]' with `IO'
Expected type: IO String
Actual type: [String]
* In a stmt of a 'do' block: content : readFiles xs
In the expression:
do content <- readFile x
content : readFiles xs
In an equation for `readFiles':
readFiles (x : xs)
= do content <- readFile x
content : readFiles xs
|
11 | content : readFiles xs
| ^^^^^^^^^^^^^^^^^^^^^^
我做错了什么,但是,我找不到正确的方法。
你能做对吗?
readFiles xs
不是列表,因此您不能在其前面添加项目。相反,它是一个 action,执行时会生成一个列表。
更具体地说,readFiles xs
的类型是 IO [String]
(IO
是可执行操作的类型),而列表的类型是 [String]
。这就是错误消息告诉您的内容:无法将类型 IO [String]
与 [String]
.
匹配
所以要得到列表,你必须执行动作,就像你正在执行readFile
readFiles (x:xs) = do
content <- readFile x
theRest <- readFiles xs
pure (content : theRest)
另请注意,当参数为空列表时,readFiles
不知道该怎么做。你应该在编译时得到一个警告,如果你不修复它,你会在运行时崩溃。
要修复,只需为空列表情况添加一个方程式:
readFiles [] = pure []
readFiles (x:xs) = do
content <- readFile x
theRest <- readFiles xs
pure (content : theRest)
我对IO有点了解。我知道您可以使用 readFile
来获取文件的内容。例如像这样:
main = do
let inputFilePath = "C:\Haskell\myawesomeprogram\files\a.txt"
content <- readFile inputFilePath
print content
调用程序:
> runghc myawesomeprogram
"AAA"
太棒了,太棒了!现在我想从多个文件中读取内容。 我试过这样的事情:
files = ["C:\Haskell\myawesomeprogram\files\a.txt", "C:\Haskell\myawesomeprogram\files\b.txt","C:\Haskell\myawesomeprogram\files\c.txt"]
main :: IO ()
main = do
filesContent <- readFiles files
print filesContent
readFiles (x:xs) = do
content <- readFile x
content : readFiles xs
这会给我以下错误信息:
myawesomeprogram.hs:6:21: error:
* Couldn't match type `[]' with `IO'
Expected type: IO String
Actual type: [String]
* In a stmt of a 'do' block: filesContent <- readFiles files
In the expression:
do filesContent <- readFiles files
print filesContent
In an equation for `main':
main
= do filesContent <- readFiles files
print filesContent
|
6 | filesContent <- readFiles files
| ^^^^^^^^^^^^^^^
myawesomeprogram.hs:9:1: error:
Couldn't match type `IO' with `[]'
Expected type: [FilePath] -> [String]
Actual type: [FilePath] -> IO String
|
9 | readFiles (x:xs) = do
| ^^^^^^^^^^^^^^^^^^^^^^^...
myawesomeprogram.hs:11:5: error:
* Couldn't match type `[]' with `IO'
Expected type: IO String
Actual type: [String]
* In a stmt of a 'do' block: content : readFiles xs
In the expression:
do content <- readFile x
content : readFiles xs
In an equation for `readFiles':
readFiles (x : xs)
= do content <- readFile x
content : readFiles xs
|
11 | content : readFiles xs
| ^^^^^^^^^^^^^^^^^^^^^^
我做错了什么,但是,我找不到正确的方法。 你能做对吗?
readFiles xs
不是列表,因此您不能在其前面添加项目。相反,它是一个 action,执行时会生成一个列表。
更具体地说,readFiles xs
的类型是 IO [String]
(IO
是可执行操作的类型),而列表的类型是 [String]
。这就是错误消息告诉您的内容:无法将类型 IO [String]
与 [String]
.
所以要得到列表,你必须执行动作,就像你正在执行readFile
readFiles (x:xs) = do
content <- readFile x
theRest <- readFiles xs
pure (content : theRest)
另请注意,当参数为空列表时,readFiles
不知道该怎么做。你应该在编译时得到一个警告,如果你不修复它,你会在运行时崩溃。
要修复,只需为空列表情况添加一个方程式:
readFiles [] = pure []
readFiles (x:xs) = do
content <- readFile x
theRest <- readFiles xs
pure (content : theRest)