另一個 Haskell 教程/Io/解決方案
外觀
< 另一個 Haskell 教程 | Io
(從 Haskell/YAHT/Io/Solutions 重定向)| 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."
注意我們不需要重複do在if內部,因為這些只是一個動作命令。
我們也可以更聰明一點,使用elem命令,它內置於 Prelude 中
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)
