另一個 Haskell 教程/Io/解答
外觀
< 另一個 Haskell 教程 | Io
| Haskell | |
|---|---|
| |
| 另一個 Haskell 教程 | |
| 前言 | |
| 介紹 | |
| 入門 | |
| 語言基礎 (解答) | |
| 型別基礎 (解答) | |
| IO (解答) | |
| 模組 (解答) | |
| 高階語言 (解答) | |
| 高階型別 (解答) | |
| 單子 (解答) | |
| 高階 IO | |
| 遞迴 | |
| 複雜性 | |
使用if,我們得到類似的東西
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name:"
name <- getLine
if name == "Simon" || name == "John" || name == "Phil"
then putStrLn "Haskell is great!"
else if name == "Koen"
then putStrLn "Debugging Haskell is fun!"
else putStrLn "I don't know who you are."
請注意,我們不需要重複dos 在ifs 中,因為這些只是一條動作命令。
我們也可以更聰明一些,使用 Prelude 中的內建 elem 命令
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name:"
name <- getLine
if name `elem` ["Simon", "John", "Phil"]
then putStrLn "Haskell is great!"
else if name == "Koen"
then putStrLn "Debugging Haskell is fun!"
else putStrLn "I don't know who you are."
當然,我們不需要把所有 putStrLns 都放在if語句中。我們可以改寫為
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name:"
name <- getLine
putStrLn
(if name `elem` ["Simon", "John", "Phil"]
then "Haskell is great!"
else if name == "Koen"
then "Debugging Haskell is fun!"
else "I don't know who you are.")
使用case,我們得到類似的東西
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name:"
name <- getLine
case name of
"Simon" -> putStrLn "Haskell is great!"
"John" -> putStrLn "Haskell is great!"
"Phil" -> putStrLn "Haskell is great!"
"Koen" -> putStrLn "Debugging Haskell is fun!"
_ -> putStrLn "I don't know who you are."
在這種情況下,實際上並沒有更簡潔。
程式碼可能看起來像這樣
module DoFile where
import IO
main = do
hSetBuffering stdin LineBuffering
putStrLn "Do you want to [read] a file, ...?"
cmd <- getLine
case cmd of
"quit" -> do putStrLn ("Goodbye!")
return ()
"read" -> do doRead; main
"write" -> do doWrite; main
_ -> do putStrLn
("I don't understand the command "
++ cmd ++ ".")
main
doRead = do
putStrLn "Enter a file name to read:"
fn <- getLine
bracket (openFile fn ReadMode) hClose
(\h -> do txt <- hGetContents h
putStrLn txt)
doWrite = do
putStrLn "Enter a file name to write:"
fn <- getLine
bracket (openFile fn WriteMode) hClose
(\h -> do putStrLn
"Enter text (dot on a line by itself to end):"
writeLoop h)
writeLoop h = do
l <- getLine
if l == "."
then return ()
else do hPutStrLn h l
writeLoop h
這裡唯一有趣的是對 bracket 的呼叫,它確保程式即使發生錯誤也能繼續執行;以及 writeLoop 函式。請注意,我們需要將 openFile(透過 bracket)返回的控制代碼傳遞給此函式,以便它知道將輸入寫入哪裡。
或者,我們可以使用 readFile 和 writeFile 建立一個不使用 bracket 的版本
doRead = do
putStrLn "Enter a file name to read:"
fn <- getLine
txt <- readFile fn
putStr txt
doWrite = do
putStrLn "Enter a file name to write:"
fn <- getLine
txt <- getWriteLines
writeFile fn txt
getWriteLines = do
l <- getLine
if l == "."
then return ""
else do lines <- getWriteLines
return (line++"\n"++lines)
