另一个 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."
当然,我们不必将所有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)