跳转到内容

Haskell/资料库/解决方案/IO

来自维基文库,一个开放世界的开放书籍
练习

编写一下我们的程序的变体,使其首先询问用户是否希望从文件读取、写入文件或退出。如果用户用“退出”做出回应,该程序应退出。如果他们用“读取”做出回应,该程序应要求他们提供一个文件名,然后将该文件打印在屏幕上(如果文件不存在,该程序可能会崩溃)。如果他们用“写入”做出回应,它应要求他们提供一个文件名,然后要求他们输入要写在文件中的文本,用“。”表示已完成。除了“.”,所有内容都应被写入文件。

例如,运行此程序可能会生成

Do you want to [read] a file, [write] a file, or [quit]?
read
Enter a file name to read:
foo
...contents of foo...
Do you want to [read] a file, [write] a file, or [quit]?
write
Enter a file name to write:
foo
Enter text (dot on a line by itself to end):
this is some
text for
foo
.
Do you want to [read] a file, [write] a file, or [quit]?
read
Enter a file name to read:
foo
this is some
text for
foo
Do you want to [read] a file, [write] a file, or [quit]?
blech
I don't understand the command blech.
Do you want to [read] a file, [write] a file, or [quit]?
quit
Goodbye!
module Main
    where

import System.IO
import Control.Exception

main = doLoop

doLoop = do
    putStrLn "Do you want to [read] a file, [write] a file, or [quit]?"
    command <- getLine
    if command == "quit"
        then return()
    else if command == "read" || command == "write"
        then do putStrLn ("Enter a file name to " ++ command)
                filename <- getLine
                if command == "read"
                    then do doRead filename
                            doLoop
                    else do doWrite filename
                            doLoop
        else doLoop

doRead filename = do
    bracket (openFile filename ReadMode) hClose
            (\h -> do contents <- hGetContents h
                      putStrLn contents)

doWriteChars handle = do
    char <- getChar
    if not (char == '.')
        then do hPutChar handle char
                doWriteChars handle
        else return ()

doWrite filename = do
    bracket (openFile filename WriteMode) hClose
            (\h -> doWriteChars h)


华夏公益教科书