By George Z. August 4, 2021
基础数据模型
Haskell 是一种纯函数式编程语言,因此它比其他编程语言更具交互性和智能性。 在本章中,我们将学习 Haskell 的基本数据模型,这些模型实际上是预定义的或以某种方式智能地解码到计算机内存中的。在本教程中,我们将使用我们网站 (https://www.tutorialspoint.com/codingground.htm) 上提供的 Haskell 在线平台。
Number
Haskell 足够聪明,可以将某个数字解码为数字。 因此,您无需像我们通常在其他编程语言的情况下那样在外部提及它的类型。 根据示例,转到您的前奏命令提示符,然后运行“2+2”并按回车键。
sh-4.3$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 2+2
您将收到以下输出结果。
4
在上面的代码中,我们只是将两个数字作为参数传递给 GHCI 编译器,而没有预先定义它们的类型,但是编译器可以轻松地将这两个条目解码为数字。现在,让我们尝试一些更复杂的数学计算,看看我们的智能编译器是否给我们正确的输出。 试试“15+(5*5)-40”
Prelude>15+(5*5)-40
根据预期输出,上述表达式产生“0”。
0
Characters
像数字一样,Haskell 可以智能地识别作为输入的字符。 转到您的 Haskell 命令提示符并键入任何带有双引号或单引号的字符。让我们提供以下行作为输入并检查其输出。
Prelude> :t "a"
它将产生以下输出
"a" :: [Char]
请记住,在提供输入时使用 (:t)。 在上面的例子中, (:t) 是包括与输入相关的特定类型。 我们将在接下来的章节中了解有关此类型的更多信息。看看下面的例子,我们将一些无效的输入作为字符传递,这又会导致错误。
Prelude> :t a
<interactive>:1:1: Not in scope: 'a'
Prelude> a
<interactive>:4:1: Not in scope: 'a'
通过错误消息“:4:1: Not in scope: `a'”,Haskell 编译器警告我们它无法识别您的输入。 Haskell 是一种用数字表示一切的语言。Haskell 遵循传统的 ASCII 编码风格。 让我们看一下下面的例子来了解更多
Prelude> '\97'
'a'
Prelude> '\67'
'C'
看看你的输入是如何被解码成 ASCII 格式的。
String
字符串只不过是字符的集合。 没有使用字符串的特定语法,但 Haskell 遵循用双引号表示字符串的传统风格。看看下面的例子,我们传递字符串“Tutorialspoint.com”。
Prelude> :t "tutorialspoint.com"
它将在屏幕上产生以下输出
"tutorialspoint.com" :: [Char]
查看整个字符串如何仅被解码为一个 Char 数组。 让我们转向另一种数据类型及其语法。 一旦我们开始实际练习,我们就会习惯所有的数据类型及其使用。
Boolean
布尔数据类型也非常简单,就像其他数据类型一样。 请看以下示例,其中我们将使用一些布尔输入(例如“True”或“False”)使用不同的布尔运算。
Prelude> True && True
True
Prelude> True && False
False
Prelude> True || True
True
Prelude> True || False
True
在上面的例子中,我们不需要提到“True”和“False”是布尔值。 Haskell 本身可以对其进行解码并进行相应的操作。 让我们用“true”或“false”修改我们的输入。
Prelude> true
它将产生以下输出
<interactive>:9:1: Not in scope: 'true'
在上面的例子中,Haskell 无法区分“true”和数字值,因此我们输入的“true”不是数字。 因此,Haskell 编译器会抛出一个错误,指出我们的输入不是它的作用域。
List and List Comprehension
和其他数据类型一样,List 也是 Haskell 中非常有用的数据类型。 例如,[a,b,c] 是一个字符列表,因此,根据定义,List 是由逗号分隔的相同数据类型的集合。与其他数据类型一样,您无需将 List 声明为 List。 Haskell 足够聪明,可以通过查看表达式中使用的语法来解码您的输入。看看下面的例子,它展示了 Haskell 如何处理列表。
Prelude> [1,2,3,4,5]
它将产生以下输出
[1,2,3,4,5]
Haskell 中的列表本质上是同构的,这意味着它们不允许您声明不同类型数据类型的列表。 任何像 [1,2,3,4,5,a,b,c,d,e,f] 这样的列表都会产生错误。
Prelude> [1,2,3,4,5,a,b,c,d,e,f]
此代码将产生以下错误
<interactive>:17:12: Not in scope: 'a'
<interactive>:17:14: Not in scope: 'b'
<interactive>:17:16: Not in scope: 'c'
<interactive>:17:18: Not in scope: 'd'
<interactive>:17:20: Not in scope: 'e'
<interactive>:17:22: Not in scope: 'f'
List Comprehension
列表理解是使用数学表达式生成列表的过程。 看下面的例子,我们使用 [output | 格式的数学表达式生成一个列表。 范围,条件]。
Prelude> [x*2| x<-[1..10]]
[2,4,6,8,10,12,14,16,18,20]
Prelude> [x*2| x<-[1..5]]
[2,4,6,8,10]
Prelude> [x| x<-[1..5]]
[1,2,3,4,5]
这种使用数学表达式创建一个 List 的方法称为 List Comprehension。
Tuple
Haskell 提供了另一种在单一数据类型中声明多个值的方法。 它被称为元组。 元组可以被视为一个列表,但是元组和列表之间存在一些技术差异。元组是不可变的数据类型,因为我们不能在运行时修改元素的数量,而列表是可变的数据类型。另一方面,List 是同构的数据类型,而 Tuple 本质上是异构的,因为一个 Tuple 内部可能包含不同类型的数据。元组由单括号表示。 看看下面的例子,看看 Haskell 如何处理一个元组。
Prelude> (1,1,'a')
它将产生以下输出
(1,1,'a')
在上面的例子中,我们使用了一个带有两个数字类型变量和一个字符类型变量的元组。