以列表形式输出_02. 列表&元组

0bcb5d2862756ae5c6f6bb7f1852b1a0.png

列表

Haskell里列表是保存相同类型的线性表,比如[1, 2, 3]就是一个整数列表。字符串"hello"只是一个语法糖,即它其实就是字符列表['h','e','l','l','o']

Prelude> [1, 2, 3, 4] ++ [9, 10, 11, 12]
[1,2,3,4,9,10,11,12]
Prelude> 1:[2, 3]
[1,2,3]
Prelude> "Steve Buscemi" !! 6
'B'

你可以用++连接两个列表,可以用:在列表前加入一个元素,可以用!!从列表中去对应下表的元素。:[]构造了列表的值,[1, 2, 3]不过是1:2:3:[]的语法糖。列表的比较就像字符串那样是按字典序排序的。

Prelude> [3, 2, 1] > [2, 1, 0]
True
Prelude> [3, 4, 2] > [3, 4]
True
Prelude> [3, 4, 2] == [3, 4, 2]
True

列表也有一些函数可以用,原文列了很多,就不多说了。

范围

数数是在常见不过的操作了,你当然不能笨笨地一个一个敲进去。Haskell提供了一个语法糖来帮你

Prelude> [1..5]
[1,2,3,4,5]
Prelude> [5,-1 .. 1]
[5]
Prelude> [5, 4 .. 1]
[5,4,3,2,1]
Prelude> [1,3 .. 5]
[1,3,5]

[first..end]first递增到end,而[first,second..end]构成了等差数列。

特别地,列表可以有无穷多元素,很像很像数学中的集合

Prelude> [1..]
-- 所有正整数
Prelude> [1,3 ..]
-- 所有正奇数
Prelude> length [1..]
-- 数不过来的,亲

怎么可能产生无穷元素的元素呢,内存不就爆炸了么?嗯,如果一口气都算出来是这样。但是这种方式只是求值策略的一种。求值策略大概有两种

  • 及早求值 表达式一被绑定就求值。见到[1..]就把所有项都算出来。这是很多语言的默认方式,但不能处理无穷、递归的情况。
  • 惰性求值 表达式只有等到需要它的值的时候才会被求值。见到[1..]不会立刻求值,你之后用当才会。比如说输出[1..]时会边算边输出。Haskell默认是惰性求值的。

列表推导式

数学中表示集合更常用的方式应该是这样,在Haskell里也有类似的语法糖

Prelude> [2 * x | x <- [1 ..], x <= 10]
[2,4,6,8,10,12,14,16,18,20

他们都具有这样的形式[exp | q, ..., q],其中

  • q只可能有两种
    • 生成式 p <- e 表示从列表e中提取各项
    • 布尔表达式,True则计算exp
  • exp计算输出列表每一项的表达式

有时候你可能并不需要具体的项

Prelude> length' xs = sum [1 | _ <- xs]

我们自己实现了函数length并命名为length'加以区分。*'也可以作为标识符的一部分,通常在最后表示一点小小的变化,跟数学老师写的板书差不多。*其中我们取xs每一项,但列表推导里面的exp并不用,所以用_就很不错。_不是一个标识符,它就表示“不在乎”,不像Python那样。

惰性求值可以让length'有几分神奇

Prelude> xs = [error "0 evaluated!", error "1 evaluated!"]
Prelude> xs !! 0
*** Exception: 0 evaluated!
Prelude> xs !! 1
*** Exception: 1 evaluated!
Prelude> length' xs
2 -- 每一项都不求值的,因为length'并不用

元组

元组与列表都是线性表,但是

  • 元组各个元素可以是不同类型
  • 元组没有:++运算,甚至不能!!那怎么取元素呢
  • 元组长度至少是2,列表可以为[]
  • 同类元素不同长度列表是一个类型的列表,但长度也决定了元组类型。我们还没提类型
Prelude> [1, 'a']
-- 类型不同不能构成列表
Prelude> (1, 'a')
(1,'a')
Prelude> 1 : [2, 3]
[1,2,3]
Prelude> 1 : (2, 3)
-- 没这操作
Prelude> [1] < [1, 2]
True
Prelude> (1, 2) < (1, 2, 3)
-- type ‘(Integer, Integer)’ 和 type ‘(Integer, Integer, Integer)’不同
Prelude> (1, 'a') < (1, 'c')
True

类型错误跟惰性求值不矛盾,静态类型语言不管咋求值,类型总是要能定下来。综上,元组往往用于已知个数和类型的时候,比如函数多个返回值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值