haskell支持两种方法表示列表或集合,一种是直接在方括号中列出每个元素,例如:[2,3,4];另一种是给出生成这些元素的规则,称为List Comprehensions(这个术语来自于Zermelo Frankel集合论中的"Axiom of Comprehension"),例如:
[ n*n | n <- [1..9] ]。
列表中的所有元素的类型必须相同的,['a', True]是错误的。haskell中设置了tuple来表示不同类型元素的集合。
第一种表示方法
这种表示法比较简单,通过几个例子很容易明白,需要注意的是“..”操作符。
[1,2,3,4,5,6]
[2, 3, 4.0] 等价于[2.0, 3.0, 4.0], 元素的类型为Double
[(1, 'a'), (0, 'b')] 这个列表中元素的类型为(Integer, Char)
[1..5] 即[1,2,3,4,5]
[1,3..8] 即:[1,3,5,7], 这里用前2个数来指明增量,默认的增量是1
[7,6..4] 即:[7,6,5,4]
[0, 0.3 .. 1] 即:[0, 0.3, 0.6, 0.9]
[2,3..2] 这个比较难于理解,可以这样理解:第2个数只是用来表明增量,并不代表实际的元素,所以等价于[2]
['a'..'e'] 即:"abcde",现在流行的语言都是把String和[Char]认为是等价的,String 是一种特殊的 List ,包含的元素是 Char类型
[1, 2*3, 9] 列表中也可以包含表达式
第二种表示方法
List Comprehensions的语法:
[e | q1, q2, ..., qk]
这里,e是一个表达式
qi或者是一个生成器,或者是一个限制条件。
生成器的形式为:v<-expr,这里v是变量,expr是表达式
限制条件就是一个布尔表达式,只有满足此条件的元素才会生成
注意:
如果有多个生成器,则右侧的生成器变化得比左侧的快。
后面出现的变量可以引用前面出现过的变量。
几个例子:
[n*n | n <- [1,3..9]]
即[1,9,25,49,81]
[(a,b) | a<-[1,2], b<-['a'..'c']]
即[(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c')]
[(x, y) | x <- [1..3], y <- [1..x]]
即[(1,1),(2,1),(2,2),(3,1),(3,2),(3,3)]
求出在20以内的勾股数
[(x, y, z) | x <- [2..20], y <- [x+1..20], z <- [y+1..20], x*x + y*y == z*z]
即[(3,4,5),(5,12,13),(6,8,10),(8,15,17),(9,12,15),(12,16,20)]
与列表有关的常用函数
length l --求列表中元素的个数
head l --提取列表的第一个元素
tail l --除第一个元素外剩余的列表
last l --提取最后一个元素
init l --除最后一个元素外剩余的列表
null l --当列表为空时返回True,非空时返回False
take n l --列表前n个元素形成的子列表
drop n l --除去数列前n个元素后,剩余的列表
e : l --将一个元素插入到列表的最左边
l !! n --提取第n个元素, 索引从0开始
reverse l --反序
l1 ++ l2 --将两个列表连成一个列表
sum l --求列表中的各元素的总和
product l --求列表中的各元素的连乘积
elem e lst --判断e是否为l中的元素
length [1..9]
9
head [1..4]
1
tail [1..4]
[2,3,4]
last [1..9]
9
init [1..9]
[1,2,3,4,5,6,7,8]
null []
True
null [1]
False
take 3 [1..9]
[1,2,3]
drop 3 [1..9]
[4,5,6,7,8,9]
99:[4,5,6]
[99, 4, 5, 6]
"abcde" !! 3
'd'
sum [1..100]
5050
product [1..10]
3628800
elem 3 [1..9]
True
elem '0' ['a'..'z']
False
head "bull" : tail "cat"
"bat"
[4,5] ++ [] ++ [8,9]
[4,5,8,9]
[null (tail [1]), head [null []]]
[True,True]