haskell的列表推导中的基本概念和其他列表功能head/tail/take/drop

haskell的列表推导中的基本概念和其他列表功能head/tail/take/drop

今天将主要介绍列表推导中的基本概念,即列表推导中的守卫和字符串推导

列表理解基础
列表推导基于数学符号,例如:{𝑥^2 | 𝑥 ∈ {1 … 5}}
(产生所有数字的集合 𝑥^2 使得 𝑥 是集合 {1…5} 的一个元素)
在 Haskell 中,你可以使用这个表达式来做同样的事情:
[x^2 | x <- [1…5]]
“|”读作“这样”,“<-”读作“从中提取”,表达式“x <- [1…5]”被称为生成器
如果我想生成一个数字及其平方对的列表,我可以这样做:
[(x,x^2) | x <- [1…5]]

多个生成器
您可以拥有多个生成器,例如:[(x,y) | x <- [1…3], y <- [10, 20]]
这是做什么的? 它从两个生成器生成所有可能的 x 和 y 组合:
[(1,10),(1,20),(2,10),(2,20),(3,10),(3,20)]
您还可以参考以前生成器中使用的变量:[(x,y) | x <- [1…3], y <- [x…3]]
它产生一组有序对:[(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]

警卫
像以前一样生成列表很有用,但如果你可以添加警卫,那就更有用了
这些是过滤生成的值的逻辑表达式,例如: [x | x <- [1…10], odd x] (生成 1 到 10 之间的奇数)
假设我有一个模块的所有学生及其分数的列表,并想找到获得第一名的学生
findFirsts :: [(String, Int)] -> [String]
findFirsts result_list = [ name | (name, mark ) <- result_list, mark >= 70]

字符串
请记住,字符串只是一种特定类型的列表(Char 列表)
因此,您可以对多态列表执行任何操作,也可以对字符串执行任何操作,包括列表推导

这个函数有什么作用?
mystery :: Char -> String -> Int
mystery x string = length [ y | y <- string, x == y]
它的意思是: 得到直到它有这个字符的长度的结果

这个函数有什么作用?
mystery2 :: x -> String -> [Int]
mystery2 x string = [ n | (y, n) <- zip string [0…], x == y]
它的意思是:此字符串中 char 的位置
这是另一个新事物:构造函数没有终止符!
这在理论上会产生一个无限列表。 但是因为当任何一个列表用完项目时 zip 都会停止,而且 Haskell 是一种惰性语言,它只生成此列表中的项目数以匹配字符串的长度。
zip 是另一个有用的库函数:它从每个列表中生成成对的连续元素,直到一个或两个列表用尽

凯撒密码The Caesar cipher
凯撒密码是一个非常简单的密码:每个明文字符只是简单地沿着字母表“移动”一个固定的偏移量(环绕在字母表的末尾)。
rot13 是 90 年代初在互联网新闻组中流行使用的一种变体,用于隐藏可能令人反感的内容、剧透或笑话的答案。
它使用偏移量为 13 的凯撒密码,使其对称。 (也就是说,您使用相同的转换来编码和解码。)

对于这项工作,我们将假设输入完全小写
我们需要的第一件事是能够从字母转换为数字并再次转换回来:

在这里插入图片描述

现在要编码一个字母,我们只需要将它移动指定的数量。
对于这个密码,我们将保留非字母字符(但假设字母是小写的)
在这里插入图片描述
挑战
如何编码整个字符串?
有多种方法可以做到!使用地图(map); 使用列表理解(list comprehension); 使用递归(recursion)

其他列表功能
标准前奏包含许多列表函数和运算符。 我们已经看到了一些:

Operator/function   Type definition
	:				a->[a]->a 
	(缺点运算符:将项目添加到头部)
	++ 				[a]->[a]->[a] 
	!!				[a]->Int->a 
	(第 n 个运算符)
	head			[a]->a
	tail			[a]->[a]
	(第一项之后的列表剩余部分)
	concat 			[[a]]->[a]
	(展平列表列表) 
	last			[a]->a 
	init			[a]->[a]
	(列表中除最后一项之外的所有项目的列表) 
	replicate 		Int->a->[a]
	(形成 arg 2 的 n 个副本的列表)
	take			Int->[a]->[a] 
	(从头部取前 n 个元素)
	drop			Int->[a]->[a]
	(从头部删除 n 个元素)
	splitAt 		Int->[a]-> ([a],[a]) 
	(在第 n 个位置拆分列表,返回一对列表)
	reverse 		[a]~>[a] 
	and				[Bool]-> Bool
	(布尔列表的合取conjunction) 
	or				[Bool]-> Bool
	(布尔列表的析取disjunction) 
	product 		[Int]->Int 
					[Float]->Float 					
	(数字列表的乘积)
	halves :: [a] -> ([a],[a])

合并排序
今天我们将开始看一下 Haskell 中归并排序的实现。
回顾:归并排序算法:将列表分成两半。 对每一半进行排序。 将已排序的列表重新合并在一起。
该算法是递归的(因为排序列表涉及排序列表!)。

总结
1.像以前一样生成列表很有用,但如果你可以添加警卫,那就更有用了。添加警卫等于添加限制。
2.这两个功能不同
mystery :: Char -> String -> Int
mystery x string = length [ y | y <- string, x == y]

mystery2 :: x -> String -> [Int]
mystery2 x string = [ n | (y, n) <- zip string [0…], x == y]
3.凯撒密码The Caesar cipher
4.其他列表功能head/tail/take/drop…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值