另一个 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."
当然,我们不需要把所有 putStrLn
s 都放在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)