cie*_*bor 1 io haskell file lines invert
我试着在考试前学习Haskell,这对我来说仍然很神奇.今天我尝试编写一个程序,它读取一个文件,然后按顺序将它的行写入另一个文件.结果?很多错误:(.这是我的代码:
import IO
readLines :: Handle -> [String] -> [String]
readLines handler list = do
eof <- hIsEOF handler
if eof then list
else do
line <- hGetLine handler
readLines handler (list ++ [line])
writeLines :: Handle -> [String] -> [String]
writeLines handler list = if length list == 0 then list
else do
line <- head list
hPutStrLn handler line
writeLines tail list
fileToList :: FilePath -> [String]
fileToList filename = do
handler <- openFile filename ReadMode
list <- (readLines handler [])
hClose handler
list
invLines :: FilePath -> FilePath -> IO ()
invLines input output = do
handler <- openFile output WriteMode
inverted <- reverse (fileToList input)
writeLines handler inverted
hClose handler
main = invLines "in.txt" "out.txt"
Run Code Online (Sandbox Code Playgroud)
如果你能解释我的错误,我将不胜感激.
好的,首先,
IO ==> System.IO
Run Code Online (Sandbox Code Playgroud)
接下来让我们看一下readLines(PS readFile在这里可以很好地工作)
readLines :: Handle -> [String] -> [String] --You have to return an IO [String] here.
readLines handler list = do
eof <- hIsEOF handler
if eof then return list --Return an IO list
else do
line <- hGetLine handler
readLines handler (list ++ [line])
Run Code Online (Sandbox Code Playgroud)
接下来writeLines(PS writeFile也有帮助)
writeLines :: Handle -> [String] -> [String] -- You have to return IO of something, I'd recommend ().
writeLines handler list = if length list == 0
then list --Change to return ()
else do
line <- head list --Should be let here. Like let line = head list
hPutStrLn handler line
writeLines tail list -- Should be writeLines handler $ tail list instead.
Run Code Online (Sandbox Code Playgroud)
接下来是 fileToList
fileToList :: FilePath -> [String] --Has to be IO [String]
fileToList filename = do
handler <- openFile filename ReadMode
list <- (readLines handler [])
hClose handler
list -- Have to use return list
Run Code Online (Sandbox Code Playgroud)
哦,你似乎反转了两次线,所以你实际上最终得到一个非常大的复制程序,在那里删除反向,你得到正确的结果.
最后的守则
import System.IO
readLines :: Handle -> [String] -> IO [String]
readLines handler list = do
eof <- hIsEOF handler
if eof
then return list
else do
line <- hGetLine handler
readLines handler (line:list)
writeLines :: Handle -> [String] -> IO ()
writeLines handler list = if length list == 0 then return ()
else do
let line = head list
hPutStrLn handler line
writeLines handler $ tail list
fileToList :: FilePath -> IO [String]
fileToList filename = do
handler <- openFile filename ReadMode
list <- (readLines handler [])
hClose handler
return list
invLines :: FilePath -> FilePath -> IO ()
invLines input output = do
handler <- openFile output WriteMode
inputLines <- fileToList input
writeLines handler inputLines
hClose handler
main = invLines "in.txt" "out.txt"
Run Code Online (Sandbox Code Playgroud)
并使用更多的库重写:
invLines input output = do
inputLines <- readFile input
writeFile output . unlines . reverse . lines $ inputLines
invLines2 input output =
readFile input >>= writeFile output . unlines . reverse . lines
Run Code Online (Sandbox Code Playgroud)
要学习的重要课程您无法从IO do块中返回正常的功能.你必须返回一些IO