Date
Nov. 21st, 2024
 
2024年 10月 21日

Post: Haskell Primer 007: 类型初识

Haskell Primer 007: 类型初识

Published 12:04 Apr 14, 2016.

Created by @ezra. Categorized in #Programming, and tagged as #Haskell.

Source format: Markdown

Table of Content

有了前面一些基础介绍,现在我们开始介绍 Haskell 中关于类型的各种知识。

由于 Haskell 支持类型推导 (Type Inference),允许我们不对类型进行显示声明,但对于初学者,有时我们可能依旧需要类型检查来帮助我们理解和学习。在 GHCi 中,可以使用 :t 表达式 命令来检查类型:

Haskell> :t 'a'
'a' :: Char
Haskell> :t True
True :: Bool
Haskell> :t (1, 'a')
(1, 'a') :: Num t => (t, Char)
Haskell> :t (False, 'a')
(False, 'a') :: (Bool, Char)
Haskell> :t 1 == 2
1 == 2 :: Bool
Haskell>

你可以将 :: 读作 "是一个"、"类型为"。

对于明确的类型,其首字母均为大写,例如刚才的示例中 'a'Char 类型。

类似的,函数也有类型,这一点在前面函数定义一文已经有过说明。定义函数时进行类型声明是一个好的习惯。

常见类型

Int

Int 类型表示整数,它是有界的 (bounded),也就是说这种类型的值在一个最小值与最大值范围之间,我们使用 GHC 时,这个最大值与最小值的界定根据不同的计算机会有所不同,一般的,如果你是用 64 位计算机,则 Int 值在 -263 与 263 - 1 之间。

Integer

Int 类似,也表示整数,但它的无界的,也就意味着这种类型的值可以极其大或及其小,远远超出 Int 表示的范围。相对的,效率要低于 Int

Float

Float 表示单精度浮点数。

Double

Double 表示双精度浮点数。两种浮点数类型的区别在于精度不同,也就是说,小数点后可用的数字位数长度不同。但相应的也会占据更多内存控件。

Bool

Bool 表示布尔 (Boolean) 值,这种类型只有 TrueFalse 两种值。

Char 与 String

Char 是字符 (Character) 类型,表示一个 Unicode 字符。例如 'a'。由字符组成的列表叫做字符串,即 String,它是 [Char] 的别名,二者完全等价,但 String 更易于书写和阅读。

元组

元组也是类型,但通常它是一个统称,其实际类型取决于元素类型和数量。理论上存在无数种类型的元组,但实际中元组中元素数量最大为 62,最小为 0,即空元组 (()),空援组也是一种类型。

类型变量

对于函数,有时需要处理多种不同类型。这不但让函数变得更加合理,增强了通用性,避免为每一种类型都定义类似函数的尴尬。举个例子,我们前面用过的 head 函数可以接受一个列表数据,不论列表元素是何种类型都返回数据。那么,我们来看看它的类型:

Haskell> :t head
head :: [a] -> a
Haskell>

刚才我们说过,类型的首字母是大写,所以此处的 a 绝不是类型。事实上,它是一个类型变量 (Type Variable),表示 a 可以是任何类型。这样,在保证类型安全的前提下,轻松的实现了一个通用函数。

类型变量的命名允许使用多个字符,例如 somename,但在习惯上,通常使用单个字符,例如 axn

使用类型变量的函数,称为多态函数 (Polymorphic Function)。

需要注意的是,当我们使用多个类型变量时,并不表示它们的类型一定不同,例如:

Haskell> :t fst
fst :: (a, b) -> a
Haskell>

这个例子中,ab 可以是同类型,可以是不同类型,但不论怎样,它们始终是 fst 函数不同的参数。

Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
开发、设计与写作皆为所长。
热爱苹果、钟情色彩。
随时恭候 垂询