List入门-haskell趣学指南

List入门-haskell趣学指南

338个读者 ssword @ yeeyan.com 12/04/2008 双语对照   原文 字体大小

简介

一点关于haskell中List的内容

List入门
BUY A DOG
Haskell 中,List同现实世界中的购物单一样重要。它是最常用的数据结构,并且十分强大,灵活地使用它可以解决掉很多问题。在本节,我们将对List,字符串和list comprehension有个初步了解。

Haskell 中,List是一种单类型的数据结构,可以用来存储多个类型相同的元素。我们可以在里面装一组数字或者一组字符,但不能字符和数字装在一起。

note:在ghci下,我们可以使用let关键字来定义一个常量。在ghci下执行let a =1与在脚本中编写a=1是等价的。

ghci>   let  lostNumbers  =  [ 4 , 8 , 15 , 16 , 23 , 48 ]  
ghci>  lostNumbers  
[ 4 , 8 , 15 , 16 , 23 , 48

如你所见,一个List由方括号括起,其中的元素用逗号分隔开来。若试图写 [1,2,'a',3,'b','c',4]这样的List,Haskell 就会报出这几个字符不是数字的错误。字符串实际上就是一组字符的List,"Hello"只是 ['h','e','l','l','o']的语法糖而已。所以我们可以使用处理List的函数来对字符串进行操作。

将两个List合并是很常见的操作,这可以通过++运算符实现。

ghci>  [1 ,2 ,3 ,4 ] ++  [9 ,10 ,11 ,12 ]  
[1 ,2 ,3 ,4 ,9 ,10 ,11 ,12 ]  
ghci>  "hello"  ++  " "  ++  "world"   
"hello world"   
ghci>  ['w' ,'o' ] ++  ['o' ,'t' ]  
"woot"

在使用++运算符处理长字符串时要格外小心(对长List也是同样), Haskell 会遍历整个的List(++符号左边的那个)。在处理较短的字符串时 问题还不大,但要是在一个5000万长度的List上追加元素,那可得执行好一会儿了。所以说,用:运算符往一个List前端插入元素会是更好的选择。

ghci>   'A' : " SMALL CAT"   
"A SMALL CAT"   
ghci>   5 :[ 1 , 2 , 3 , 4 , 5 ]  
[5 , 1 , 2 , 3 , 4 , 5

:运算符可以连接一个元素到一个List或者字符串之中,而++运算符则是连接两个List。若要使用++运算符连接单个元素到一个List之中,就用方括号把它括起使之成为单个元素的List。

[1,2,3]实际上是1:2:3:[]的语法糖。[]表示一个空List,若要从前端插入3,它就成了[3],再插入2,它就成了[2,3],以此类推。

Note:[],[[]],[[],[],[]]是不同的。第一个是一个空的List,第二个是含有一个空List的List,第三个是含有三个空List的List。

若是要按照索引取得List中的元素,可以使用!!运算符,索引的下标为0。

ghci>   "Steve Buscemi"  !!  6   
'B'   
ghci>  [ 9.4 , 33.2 , 96.2 , 11.2 , 23.25 ] !!  1   
33.2  

但你若是试图在一个只含有4个元素的List中取它的第6个元素,就会报错。要小心!

List同样也可以用来装List,甚至是List的List的List:

ghci>   let  b  =  [[ 1 , 2 , 3 , 4 ],[ 5 , 3 , 3 , 3 ],[ 1 , 2 , 2 , 3 , 4 ],[ 1 , 2 , 3 ]]  
ghci>  b  
[[1 , 2 , 3 , 4 ],[ 5 , 3 , 3 , 3 ],[ 1 , 2 , 2 , 3 , 4 ],[ 1 , 2 , 3 ]]  
ghci>  b  ++  [[ 1 , 1 , 1 , 1 ]]  
[[1 , 2 , 3 , 4 ],[ 5 , 3 , 3 , 3 ],[ 1 , 2 , 2 , 3 , 4 ],[ 1 , 2 , 3 ],[ 1 , 1 , 1 , 1 ]]  
ghci>  [ 6 , 6 , 6 ]:b  
[[6 , 6 , 6 ],[ 1 , 2 , 3 , 4 ],[ 5 , 3 , 3 , 3 ],[ 1 , 2 , 2 , 3 , 4 ],[ 1 , 2 , 3 ]]  
ghci>  b !!  2   
[1 , 2 , 2 , 3 , 4 ]  

List中的List可以是不同长度,但必须得是相同的类型。如不可以在List中混合放置字符和数组相同,混合放置数值和字符的List也是同样不可以的。

当List内装有可比较的元素时,使用 < , <= , >>=可以比较List的大小。它会先比较第一个元素,若它们的值相等,则比较下一个,以此类推。


ghci>  [ 3 , 2 , 1 ]  >  [ 2 , 1 , 0 ]  
True   
ghci>  [ 3 , 2 , 1 ]  >  [ 2 , 10 , 100 ]  
True   
ghci>  [ 3 , 4 , 2 ]  >  [ 3 , 4 ]  
True   
ghci>  [ 3 , 4 , 2 ]  >  [ 2 , 4 ]  
True   
ghci>  [ 3 , 4 , 2 ]  ==  [ 3 , 4 , 2 ]  
True  


还可以对LIst做啥?如下是几个常用的函数:

head返回一个List的头部,也就是List的首个元素。

ghci>  head [ 5 , 4 , 3 , 2 , 1 ]  
5   

tail返回一个LIst的尾部,也就是List除去头部之后的部分。


ghci>  tail [ 5 , 4 , 3 , 2 , 1 ]  
[4 , 3 , 2 , 1 ]  

last返回一个LIst的最后一个元素。


ghci>  last [ 5 , 4 , 3 , 2 , 1 ]  
1   

init返回一个LIst出去最后一个元素的部分。

ghci>  init [ 5 , 4 , 3 , 2 , 1 ]  
[5 , 4 , 3 , 2 ]  

 

如果我们把List当做一头怪兽,那这就是它的样子:

list monster

试一下,若是取一个空List的head又会怎样?

ghci>  head []  
*** ExceptionPrelude .head: empty list 

omg,它翻脸了!怪兽压根就不存在,head又从何而来?在使用head,tail,last和init时要小心别用到空的List上,这个错误不会在编译时被捕获。所以说做些工作以防止从空List中取值会是个好的做法。

length返回一个List的长度。

ghci>  length [ 5 , 4 , 3 , 2 , 1 ]  
5  

null检查一个List是否为空。如果是,则返回True,否则返回False。应当避免使用xs==[]之类的语句来判断List是否为空,使用null会更好。

ghci>  null [ 1 , 2 , 3 ]  
False   
ghci>  null []  
True  

reverse将一个List反转

ghci>  reverse [ 5 , 4 , 3 , 2 , 1 ]  
[1 , 2 , 3 , 4 , 5

take返回一个List的前几个元素,看:

ghci>  take  3  [ 5 , 4 , 3 , 2 , 1 ]  
[5 , 4 , 3 ]  
ghci>  take  1  [ 3 , 9 , 3 ]  
[3 ]  
ghci>  take  5  [ 1 , 2 ]  
[1 , 2 ]  
ghci>  take  0  [ 6 , 6 , 6 ]  
[] 

如上,若是图取超过List长度的元素个数,只能得到原List。若take 0个元素,则会得到一个空List!

drop与take的用法大体相同,它会删除一个List中的前几个元素。

ghci>  drop  3  [ 8 , 4 , 2 , 1 , 5 , 6 ]  
[1 , 5 , 6 ]  
ghci>  drop  0  [ 1 , 2 , 3 , 4 ]  
[1 , 2 , 3 , 4 ]  
ghci>  drop  100  [ 1 , 2 , 3 , 4 ]  
[]  

maximum返回一个List中最大的那个元素。

miniimun返回最小的。

ghci>  minimum [ 8 , 4 , 2 , 1 , 5 , 6 ]  
1   
ghci>  maximum [ 1 , 9 , 2 , 3 , 4 ]  
9   

sum返回一个List中所有元素的和。

product返回一个List中所有元素的积。

ghci>  sum [ 5 , 2 , 1 , 6 , 3 , 2 , 5 , 7 ]  
31   
ghci>  product [ 6 , 2 , 1 , 2 ]  
24   
ghci>  product [ 1 , 2 , 5 , 6 , 7 , 9 , 2 , 0 ]  
0   

elem判断一个元素是否在包含于一个List,通常以中缀函数的形式调用它。

ghci>   4   `elem`  [ 3 , 4 , 5 , 6 ]  
True   
ghci>   10   `elem`  [ 3 , 4 , 5 , 6 ]  
False  

这就是几个基本的List操作函数,我们会在往后的一节中了解更多的函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值