Haskell奇偶索引列表拆分函数逻辑解析求助
解析Haskell递归拆分奇偶索引列表的逻辑
先明确需求:我们要把输入列表按元素的索引奇偶性拆分(索引从0开始计数)——偶数索引(0、2、4...)的元素放到第一个列表,奇数索引(1、3、5...)的元素放到第二个列表。
逐行解析递归代码
func :: [Int] -> ([Int], [Int]) func [] = ([], []) func [x] = ([x], []) func (x:y:xs) = (x:odds, y:evens) where (odds, evens) = func xs
基础情况1:空列表
func [] = ([], []):空列表没有元素,拆分结果自然是两个空列表,逻辑自洽。基础情况2:单元素列表
func [x] = ([x], []):单个元素的索引是0(偶数),所以它属于第一个列表,第二个列表为空。核心递归逻辑
当列表至少有两个元素时,匹配模式x:y:xs:x是原列表的第0位元素(偶数索引),y是原列表的第1位元素(奇数索引)xs是去掉前两个元素后的剩余列表,此时xs中每个元素的索引,相对于原列表来说都增加了2——比如xs的第0位元素对应原列表的第2位(还是偶数索引),xs的第1位对应原列表的第3位(还是奇数索引)。- 递归调用
func xs得到的(odds, evens),正是xs中偶数索引、奇数索引元素组成的两个列表。 - 把
x拼到odds前面,就得到了原列表所有偶数索引的元素;把y拼到evens前面,就得到了原列表所有奇数索引的元素。
用示例输入走一遍递归流程
以输入[44,8,11,23]为例:
- 调用
func [44,8,11,23],匹配x=44, y=8, xs=[11,23] - 先计算
func [11,23],匹配x=11, y=23, xs=[] - 计算
func [],返回([], []) - 回到
func [11,23],得到(11:[], 23:[])→([11], [23]) - 回到最外层调用,得到
(44:[11], 8:[23])→([44,11], [8,23]),和预期结果一致。
关于变量命名的说明
代码里的odds和evens容易和Haskell内置的odd/even函数混淆,但这里的命名是针对**剩余列表xs**的:odds是xs中偶数索引的元素(对应原列表的偶数索引),evens是xs中奇数索引的元素(对应原列表的奇数索引),只是命名上有点反直觉,理解递归逻辑后就不会混淆了。
内容的提问来源于stack exchange,提问作者Gabriel Monteiro Silva
相关产品推荐
相关产品推荐

