类型#
类型声明#
<name>, ... :: <type>
:::声明变量类型;同一类型的数据必定具有相同操作;
可同时声明多个变量,不同变量用逗号分隔;
Haskell 为强静态类型语言,一切皆有类型,因此必须声明变量的类型,提高代码的安全性;
Haskell 支持类型推断,因此无需声明所有变量;
GHCi 中,
:type或:t可查看表达式类型;Prelude> :type 'a' 'a' :: Char Prelude> :type True True :: Bool Prelude> :t 4 == 5 4 == 5 :: Bool Prelude> :t "Hello!" "Hello!" :: [Char]
变量声明#
<name> = <value>
=:- 声明变量的值为
value; - Haskell 中,
=表示定义,而非赋值;
- 声明变量的值为
- 命名:
- 大小写拉丁字母、数字、下划线以及单引号
'为合法字符,但只能以小写字母或下划线开头; - Haskell 通常使用驼峰命名法;
- 大小写拉丁字母、数字、下划线以及单引号
- 变量一旦声明,在同一程序内便不能更改,否则报错;
- 在 Haskell 中,变量不是储存数据的容器,变量只是数据的别名;
1x :: Int -- x 有类型 Int
2x = 3 -- x **默认** 为 3
3x = 4
4-- test.hs:3:1: error:
5-- Multiple declarations of ‘x’
6-- Declared at: test.hs:2:1
7-- test.hs:3:1
基本数据类型#
Int:整数,最值取决于 CPU 架构,在 64 位系统上,Int的取值范围为\(\pm2^{63}\);biggestInt, smallestInt :: Int biggestInt = maxBound -- 该机器上的最大整数 smallestInt = minBound -- 该机器上的最小整数
Integer:整数,最值取决于计算机内存容量;reallyBig :: Integer reallyBig = 2 ^ (2 ^ (2 ^ (2 ^ 2)))
Float:单精度浮点数,用 32 位来表示;f1, f2 :: Float f1 = 4.584234 f2 = 6.2831e-30
Double:双精度浮点数,用 64 位来表示;d1, d2 :: Double d1 = 4.584234234230943 d2 = 6.2831e-300
Bool:布尔值,只有True和False两种;b1, b2 :: Bool b1 = True b2 = False
Char:单个 Unicode 字符,由单引号包围;c1, c2 :: Char c1 = 'x' c2 = '棒'
String:字符串,由双引号包围,其实质是一组字符列表;s :: String s = "Hello, Haskell!"
类型注释#
<object> :: <type>
- 类型注释:对对象类型的注释,指定对象的类型;
- 类型注释不一定出现在一行的末尾,可以通过括号改变类型注释的优先级;
exp1 = read "2" -- *** Exception: Prelude.read: no parse
exp2 = read "2" :: Int -- 2
exp3 = read "2" :: Float -- 2.0
exp4 = succ (read "2" :: Int) -- 3
类型变量#
类型变量:表示任意类型,即该表达式类型无关;
备注
类型变量与其他语言中的泛型函数类似,但更强大。
多态函数:使用了类型变量的函数;
多态常量:使用了类型变量且仅声明了一个类型的变量;
命名:
Haskell 允许类型变量为多字符,但约定俗成以单个小写字母表示;
head :: [a] -> a -- 函数 'head' 取出并返回列表的第一个元素,列表元素可为任意类型
不同字符不一定代表不同类型;
fst :: (a, b) -> a -- 'a' 和 'b' 为不同的类型变量,但两者的类型不一定不同 -- 这里仅表示返回值的类型与数对中的第一个元素类型相同
类型类#
(<typeClass> <typeVariable>, ...) => <typeVariable> -> ...
类型类:
- 用于约束类型的接口;
- 一种类型可以是多个类型类的成员,一个类型类也可以有多个类型成员;
语法格式:
- 类型约束:
- 使用小括号
()包围,在此约束类型; <typeClass> <typeVariable>表示类型变量<typeVariable>为类型类<typeClass>的成员;- 多个类型约束用逗号
,分隔; - 当只有一个类型约束时,括号可省略;
- 使用小括号
=>:定义类型约束,分隔类型约束和类型变量;- 类型变量:语法与函数定义相同;
(==) :: Eq a => a -> a -> Bool -- '(==)' 接受两个任意类型的参数并返回布尔值 -- 类型变量 'a' 属于 'Eq' 类型类
- 类型约束:
常用类型类#
Eq:可判断相等性(==和/=),凡可比较相等性的类型都属于此类;elem :: (Foldable t, Eq a) => a -> t a -> Bool -- 若参数存在于列表中,则函数 'elem' 返回 'True'(成员判断) -- 该函数使用 '(==)' 和 '(/=)' 进行判断
Ord:可比较大小;- 除函数外,前文中的所有类型都属于此类;
Ord类型类的成员也必须是Eq的成员;
compare :: Ord a => a -> a -> Ordering -- 函数 'compare' 比较两个参数,并返回表示两者关系的字符串 -- 'GT'(大于),'EQ'(等于),或 'LT'(小于) -- 比较的参数属于 'Ord' 类型类
Show:可用字符串表示,除函数外的所有类型都属于此类;show :: Show a => a -> String
Read:可将字符串转为Read的某个成员;read :: Read a => String -> a
Enum:可枚举,有()、Bool、Char、Ordering、Int、Integer、Float和Double,该类型的值具有后继值和前趋值;enumFromTo :: Enum a => a -> a -> [a]
Bounded:具有上限和下限;minBound :: Bounded a => a -- 多态常量
Num:具有数字属性,所有数字都是多态常量;(*) :: Num a => a -> a -> a
Integral:整数数字,包含成员Int和Integer;fromIntegral :: (Integral a, Num b) => a -> b
Floating:浮点数数字,包含成员Float和Double;cos :: Floating a => a -> a
Foldable:可折叠类型,可理解为可迭代序列,Foldable t => t a表示数据为可折叠类型t,该数据下的元素类型为a;foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b