Logo
Section 1 / 12

数值类型

交互式地探索 Haskell 的一些基本数值类型。

检查点

数值类型

交互式地探索 Haskell 的一些基本数值类型。

Haskell 中最核心的两个概念是 类型 和 函数。

  • 类型 是具有相似行为的值的集合,例如数字或字符串。
  • 函数 可以用来将一种类型的值映射到另一种类型。

在本节课中,我们将学习 Haskell 中一些最基本的数值类型,以及作用于这些类型的预定义函数。

GHCI

本课中的示例将使用 ghci,这是随 Glasgow Haskell 编译器(GHC)一起提供的交互式 Haskell 解释器。ghci 是一种所谓的 REPL,它会:

  • R 读取你的输入(一个 Haskell 表达式)
  • E 评估该表达式
  • P 打印结果
  • L 循环(即你可以反复输入表达式)

你可以使用下面的工具来输入本课的示例,或者直接在 ghci 中进行尝试。

Terminal

数字

在 GHCI 中,你应该看到类似这样的提示符:

1GHCi, version 8.8.3: https://www.haskell.org/ghc/ :? for help 2Prelude>

我们从一些简单的算术运算开始:

1Prelude> 1 + 2 23 3Prelude> 5 * (7 - 1) 430 5Prelude> 3 / 2 61.5

数值表达式按我们预期的方式进行计算。第一个例子中,1 和 2 是数值类型的值,+ 是一个将两个数合并得到它们和的函数。

Haskell 中有多种数值类型。最重要的包括:

  • Int 用于整数(通常是 64 位),如 5、0、-32。
  • Integer 用于任意大小的整数(在其他语言中常称为“大整数”)。
  • Double 用于 64 位浮点数,如 1.5、-0.007。

运算符 +、*、- 可以用于上述任意类型,但 / 不适用于整数。

类型推断与类型注解

请注意,在上面的表达式中,我们无需指定数字的类型。这是因为 Haskell 使用 类型推断 自动确定表达式的类型。这可以通过检查表达式中出现的值和函数来完成。例如,由于除法运算符 / 不能用于整数之间,因此 3 / 2 的类型不可能是 Int。

不过,我们也可以显式地 标注 值的类型。例如,可以这样写:

1Prelude> (1 :: Int) + (2 :: Int) 23

一般来说,类型注解是可选的,但在值的类型不明确时,添加类型注解可以使代码更清晰。


让我们用类型注解来演示 / 无法作用于整数:

1Prelude> (3 :: Int) / (2 :: Int) 2 3<interactive>:12:1: error: 4 • No instance for (Fractional Int) arising from a use of ‘/’ 5 • In the expression: (3 :: Int) / (2 :: Int) 6 In an equation for ‘it’: it = (3 :: Int) / (2 :: Int)

事实上,尝试将一个 Int 除以另一个 Int 会产生 类型错误。错误信息解释了原因:Haskell 期望 / 的参数是分数类型,但实际传入的是整数。

通常情况下,我们只能使用算术运算符组合相同类型的值,否则会出现类型错误。

1Prelude> (2 :: Int) + (3 :: Double) 2 3<interactive>:8:15: error: 4 * Couldn't match expected type `Int' with actual type `Double' 5 * In the second argument of `(+)', namely `(3 :: Double)' 6 In the expression: (2 :: Int) + (3 :: Double) 7 In an equation for `it': it = (2 :: Int) + (3 :: Double)

类型错误由编译器在称为 类型检查 的编译阶段发现,该阶段也负责类型推断。包含类型错误的 Haskell 程序无法成功编译。类型检查的优势在于,潜在的错误可以在编译阶段被发现,而不会导致程序运行时出现错误。

Quiz

单选题

为什么表达式 3.5 + (3 :: Int) 会产生类型错误?

1 / 1

简介

数字的预定义函数