另一个 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)
