跳转到内容

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 关键字。
华夏公益教科书