跳轉到內容

Haskell/解決方案/簡單的輸入和輸出

來自Wikibooks,開放世界的開放書籍

← 返回簡單的輸入和輸出

回到現實世界

[編輯 | 編輯原始碼]
練習
在型別基礎章節中,我們提到過openWindow 函式 的型別已被簡化。您認為它的型別實際上應該是什麼?

在型別基礎中,我們說

您需要開啟一個新視窗,其中包含他們可以更改的所有選項。讓我們看看此函式的型別簽名

openWindow :: WindowTitle -> WindowSize -> Window

但是,開啟視窗不僅意味著建立它,還意味著將其繪製到螢幕上。因此,結果必須具有IO 型別,就像putStrLn 一樣。真正的簽名應該是

openWindow :: WindowTitle -> WindowSize -> IO Window

可以在HGL 包中找到具有此類簽名(除了名稱略有不同)的openWindow 函式的真實示例。

使用do 順序執行操作

[編輯 | 編輯原始碼]
練習

編寫一個程式,提示使用者輸入直角三角形的底和高,計算其面積並將其列印到螢幕上。互動應該類似於

The base?
3.3
The height?
5.4
The area of that triangle is 8.91
提示:您可以使用read 函式將使用者字串(如“3.3”)轉換為數字(如 3.3),並使用show 函式將數字轉換為字串。
main = do
  putStrLn "The base?"
  base <- getLine
  putStrLn "The height?"
  height <- getLine
  putStrLn ("The area of that triangle is " ++ show (0.5 * read base * read height))

請注意,read 的返回型別是從其所在的表示式的型別推斷出來的。0.5*read("10.0") 按預期計算結果為 5.0。read("10.0") 會導致錯誤。在這種情況下,必須指定數值型別:例如,read "10.0" ::Double。

控制操作

[編輯 | 編輯原始碼]
練習

編寫一個程式,提示使用者輸入其姓名。如果姓名是 Simon、John 或 Phil 之一,則告訴使用者您認為 Haskell 是一種很棒的程式語言。如果姓名是 Koen,則告訴他們您認為除錯 Haskell很有趣(Koen Classen 是參與 Haskell 除錯的人員之一);否則,告訴使用者您不知道他是誰。

(就語法而言,有幾種不同的方法可以做到這一點;至少編寫一個使用if / then / else 的版本。)

使用if-語句

main = do
  putStrLn "Hello, what is your name?"
  name <- getLine
  if name == "Simon" || name == "John" || name == "Phil"
     then putStrLn "I think Haskell is a great programming language."
     else if name == "Koen"
             then putStrLn "I think debugging Haskell is fun."
             else putStrLn "Sorry, I don't know you."

使用where 塊的替代方法

main = do
  putStrLn "Hello, what is your name?"
  name <- getLine
  putStrLn (message name)
    where
    greatlanguage   = "I think Haskell is a great programming language."
    message "Simon" = greatlanguage
    message "John"  = greatlanguage
    message "Phil"  = greatlanguage
    message "Koen"  = "I think debugging Haskell is fun."
    message _       = "Sorry, I don't know you."

操作在顯微鏡下

[編輯 | 編輯原始碼]
練習
  1. 為什麼 let 繫結的非甜點版本需要額外的do 關鍵字?
  2. 您是否總是需要額外的do
  3. (額外獎勵)奇怪的是,當我們在本書開頭使用直譯器時,let 不帶in 正是我們編寫事物的方式。為什麼您可以在直譯器中省略in 關鍵字,而必須在鍵入原始檔時將其包含在內?
  1. 一個let name = value in thing繫結與thing具有相同的型別。因為我們希望繫結成為一個 IO 操作,所以thing需要成為一個 IO 操作,所以我們需要一個do關鍵字。
  2. 不,並非總是如此。就像在“普通”程式碼中一樣,如果只有一個 IO 操作跟隨它,則可以省略do關鍵字。
  3. GHCi 直譯器就像一個大型的 do 塊,帶有一些額外的魔法,以便它將普通表示式轉換為 IO 操作。就像在任何 do 塊中一樣,您可以省略in 關鍵字。
華夏公益教科書