跳轉到內容

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)


華夏公益教科書