Haskell - 基本数据模型
Haskell 是一种纯函数式编程语言,因此它比其他编程语言更加交互性和智能。在本章中,我们将学习 Haskell 的基本数据模型,这些模型实际上是预定义的,或者以某种智能方式被解码到计算机内存中。
在本教程中,我们将使用网站上提供的 Haskell 在线平台(https://www.example.com
数字
Haskell 足够智能,能够将某些数字解码为 number。因此,您无需像在其他编程语言中那样显式指定其类型。例如,打开 prelude 命令提示符,直接运行 "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 compiler,而没有预定义它们的类型,但 compiler 能够轻松地将这两个输入解码为数字。
现在,让我们尝试一个稍微复杂的数学计算,看看我们的智能 compiler 是否给出正确输出。试试 "15+(5*5)-40"。
Prelude> 15+(5*5)-40
上述表达式按照预期输出 "0"。
0
字符
像数字一样,Haskell 能够智能地识别输入给它的字符。打开 Haskell 命令提示符,输入任何字符,用双引号或单引号括起来。
让我们提供以下行作为输入并检查其输出。
Prelude> :t "a"
它将产生以下输出 −
"a" :: [Char]
记住,在提供输入时使用 (:t)。在上面的例子中,(:t) 用于包含与输入相关的特定类型。我们将在后续章节中学习更多关于这种类型的内容。
看下面的例子,我们传递了一个无效的 char 输入,从而导致错误。
Prelude> :t a <interactive>:1:1: Not in scope: 'a' Prelude> a <interactive>:4:1: Not in scope: 'a'
通过错误消息 "<interactive>:4:1: Not in scope: `a'",Haskell compiler 警告我们它无法识别您的输入。Haskell 是一种一切都用数字表示的语言。
Haskell 遵循传统的 ASCII 编码风格。让我们看下面的例子以了解更多 −
Prelude> '\97' 'a' Prelude> '\67' 'C'
看您的输入如何被解码为 ASCII 格式。
字符串
string 只是字符的集合。没有特定的 string 语法,但 Haskell 遵循用双引号表示 string 的传统风格。
看下面的例子,我们传递了字符串 example.com。
Prelude> :t "example.com"
它将在屏幕上产生以下输出 −
"example.com" :: [Char]
看整个字符串如何被解码为 Char 数组。让我们转向其他数据类型及其语法。一旦我们开始实际练习,我们将习惯所有数据类型及其用法。
Boolean
Boolean 数据类型和其他数据类型一样,也非常直观。看下面的例子,我们将使用一些 Boolean 输入如 "True" 或 "False" 来执行不同的 Boolean 操作。
Prelude> True && True True Prelude> True && False False Prelude> True || True True Prelude> True || False True
在上面的例子中,我们无需说明 "True" 和 "False" 是 Boolean 值。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 如何处理 List。
Prelude> [1,2,3,4,5]
它将产生以下输出 −
[1,2,3,4,5]
Haskell 中的 List 是同质的,这意味着它们不允许声明不同类型数据元素的列表。像 [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
List comprehension 是使用数学表达式生成列表的过程。看下面的例子,我们使用格式为 [output | range ,condition] 的数学表达式生成列表。
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 提供了另一种在单个数据类型中声明多个值的方式。它被称为 Tuple。Tuple 可以被视为 List,但 Tuple 和 List 之间有一些技术区别。
Tuple 是一种不可变数据类型,因为我们无法在运行时修改元素的数量,而 List 是一种可变数据类型。
另一方面,List 是同质数据类型,但 Tuple 是异质的,因为 Tuple 可以包含不同类型的数据。
Tuple 用单个括号表示。看下面的例子,了解 Haskell 如何处理 Tuple。
Prelude> (1,1,'a')
它将产生以下输出 −
(1,1,'a')
在上面的例子中,我们使用了一个包含两个 number 类型变量和一个 char 类型变量的 Tuple。