Haskell/Libraries/Solutions/IO

From Wikibooks, open books for an open world
Jump to navigation Jump to search
Exercises

Write a variation of our program so that it first asks whether the user wants to read from a file, write to a file, or quit. If the user responds with "quit", the program should exit. If they respond with "read", the program should ask them for a file name and then print that file to the screen (if the file doesn't exist, the program may crash). If they respond with "write", it should ask them for a file name and then ask them for text to write to the file, with "." signaling completion. All but the "." should be written to the file.

For example, running this program might produce:

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)