Haskell 笔记 (二)基本知识

基本知识

逻辑运算符

逻辑运算符
布尔值Ture, False
逻辑与&&
逻辑或
逻辑非not
相等,不相等==, /=

函数

前缀函数(prefix function):大多数为前缀函数,调用时格式为:先是函数名,后跟参数列表,中间都是空格分开, 如: min 8 2
中缀函数(infix function): *就是中缀函数,夹在两个参数中间。

通过’'可以将前缀函数,转换为中缀函数:

//前缀形式
ghci> div 80 16

等价为:

//中缀形式
ghci> 80 'div' 16

列表

列表运算符
运算符功能例子
++拼接两个列表[1, 3, 5] ++ [6]=>[1, 3, 5, 6]
:将元素插入表头[1] : [2, 3, 5, 6] => [1, 2, 3, 5, 6]
!!访问列表中元素, 下标从0开始[1, 3, 5] !! 1 => 3
<,>,<=,>=比较两个列表大小[3, 2, 1] > [2, 1, 0]=>True
列表函数
函数功能例子
head返回列表的头部,也就是第一个元素head [5, 4, 3, 2, 1]=>5
tail返回列表的尾部,也就是除了头部之后的部分tail [5, 4, 3, 2, 1]=>[4, 3, 2, 1]
last返回列表的最后一个元素last [5, 4, 3, 2, 1]=>1
init返回列表除了最后一个元素的部分init [5, 4, 3, 2, 1]=>[5, 4, 3, 2]
length返回列表的长度length [5, 4, 3, 2, 1]=>5
null检查列表是否为空null [5, 4, 3, 2, 1]=>False
reverse反转列表reverse [5, 4, 3, 2, 1]=>[1, 2, 3, 4, 5]
take返回指定列表的前几个元素take 2 [5, 4, 3, 2, 1]=>[5, 4]
drop删除指定列表的前几个元素drop 2 [5, 4, 3, 2, 1]=>[3, 2, 1]
maxinum返回列表的最大的元素maxinum [5, 4, 3, 2, 1]=>5
mininum返回列表的最小的元素mininum [5, 4, 3, 2, 1]=>1
sum返回列表的所有元素的和sum [5, 4, 3, 2, 1]=>15
product返回列表的所有元素的积product [5, 4, 3, 2, 1]=>120
elem判断一个元素是否在列表中elem 4 [5, 4, 3, 2, 1]=>True

区间

通过区间可以构造列表,其中的值必须是可枚举的,或者说,是可以排序的。

Prelude> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Prelude> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"
Prelude> ['K'..'Z']
"KLMNOPQRSTUVWXYZ"
Prelude>

区间可以调整步长

Prelude> [2, 4..20]
[2,4,6,8,10,12,14,16,18,20]
Prelude> [3, 6..20]
[3,6,9,12,15,18]

为什么[2, 2…20]不行?

Prelude> [2,2..20]
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,22,2,2,2,2,2...

步长不是第一个数,而是通过第二个数减去第一个数计算出来的。
[2,2…20]:2-2=0, 步长成了0,一直不会到20,所以结束不了。

[20…1] 为什么为空?

ghci>[20..1]
[]

[20…1]没有提供步长,Haskell会默认构造一个空的列表,随后从区间的下限开始,不停的增长等于上限为止,20已经大于1了,所以是空。

也就是说步长默认是+1的,如果是-1,必须提供步长,[20,19…1]

ghci>[20,19..1]
[20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]

如果不表明区间上限,将得到一个无限长度列表

ghci>[20,19..]
[20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31,-32,-33,-34,-35,-36,-37,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-74,-75,-76,-77,-78,-79,-80,-81,-82,-83,-84,-85,-86......

可以通过take取前几个

ghci>take 10 [20,19..]
[20,19,18,17,16,15,14,13,12,11]

另外几种生成无限列表的函数:

  1. cycle 函数: 接受一个列表作为参数,并返回一个无限列表
ghci>take 10 (cycle [1, 2, 3])
[1,2,3,1,2,3,1,2,3,1]
ghci>take 14 (cycle "LOL ")
"LOL LOL LOL LO"
  1. repeate 函数: 接受一个值作为参数,并返回一个无限列表
ghci>take 10 (repeat 6)
[6,6,6,6,6,6,6,6,6,6]
  1. replicate 函数: 一个参数表示列表的长度,一个参数表示要复制的值。
ghci>replicate 10 6
[6,6,6,6,6,6,6,6,6,6]

由于浮点数只能实现有限精度,最好不要在区间中使用浮点数。

ghci>[0.1, 0.2..1]
[0.1,0.2,0.30000000000000004,0.4,0.5,0.6,0.7000000000000001,0.8,0.9,1.0]
ghci>[0.1, 0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]

列表推导式

列表推导式是一种过滤,转换或者组合列表的方法

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

“|” 后 x <- [1…10] : x绑定1-10每个元素

“|” 前 x*2 : 输出

还可以对绑定值增加过滤,形式为[输出 | 绑定,过滤],

如[x*2 | x <- [1…10], x > 12]

ghci> [x*2 | x <- [1..10], x*2 > 12]
[14,16,18,20]
ghci> [x*2 | x <- [1..10], x > 6]
[14,16,18,20]

将推导式设置为函数, xs是列表,绑定到x,对其中x为奇数的执行“ if x < 10 then “BOOM!” else “BANG!” ”

x <- xs, odd x 使x绑定到 7, 9, 11, 13

ghci> boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
ghci> boomBangs [7..13]
["BOOM!","BOOM!","BANG!","BANG!"]

多个列表,结果是多个表元素的组合情况

ghci> [x + y | x <- [1..5], y <- [10, 100, 1000]]
[11,101,1001,12,102,1002,13,103,1003,14,104,1004,15,105,1005]
ghci> [x * y | x <- [1..5], y <- [10, 100, 1000]]
[10,100,1000,20,200,2000,30,300,3000,40,400,4000,50,500,5000]

元组

元组: 将多个异构的值合成为一个单一值。长度固定。

长度为2的元组叫做序对(pair)
长度为3的元组叫做三元组(triple)

序对的操作:

  1. fst : 返回首项
  2. snd : 返回尾项
  3. zip : 通过2个列表生成序对, 2个列表不一样长时,以短的为准。

例题:
使用Haskell找出满足下列条件的三角形

  • 三个表都为整数
  • 三个边长度都小于等于10
  • 周长为24的三角形
ghci> [(x,y,z) | x<-[1..10], y<-[1..10], z<-[1..10], x*x + y*y ==z*z, x+y+z==24]
[(6,8,10),(8,6,10)]

解题思路:先初始化集合将其变形,在通过过滤条件缩小计算范围。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值