Haskell生成两个范围的二元索引元组列表,代码异常求助
现有代码问题分析
- 递归终止逻辑错误,分支覆盖不全
你定义的case分支未覆盖(0,1)/(1,0)这类边界输入,这类输入会直接命中(0,0)的终止分支返回[(0,0)],导致递归拼接时出现重复的(0,0)。以你输入(0,3)的执行过程为例:
getAll (0,3)=(0,2) : getAll (0,2)getAll (0,2)=(0,1) : getAll (0,1)getAll (0,1)=(0,0) : getAll (0,0)getAll (0,0)=[(0,0)]
最终拼接结果为[(0,2), (0,1), (0,0), (0,0)],和你遇到的问题完全吻合。
- 未覆盖双维度非0的通用场景
你当前的代码仅处理了x为0或y为0的单维度场景,无法生成x、y都大于0时的双维度组合,比如需求示例的输入(2,3)完全无法被现有代码支持。
解决方案
方案1:列表生成式实现(推荐)
Haskell列表生成式天然支持笛卡尔积运算,一行代码即可满足需求:
getAll :: (Int, Int) -> [(Int, Int)] getAll (x, y) = [(i, j) | i <- [0 .. x-1], j <- [0 .. y-1]]
测试输入(2,3)可直接输出[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)],完全匹配需求。
方案2:纯递归实现
如果需要手写递归实现逻辑,可参考如下代码:
getAll :: (Int, Int) -> [(Int, Int)] -- 终止条件:第一维度无取值时返回空列表 getAll (0, _) = [] getAll (x, y) = generateY (x-1) y ++ getAll (x-1, y) where -- 生成第一维度固定为a时,第二维度的所有合法元组 generateY a b | b <= 0 = [] | otherwise = (a, b-1) : generateY a (b-1)
该实现没有重复值问题,输入(1,3)会返回[(0,2),(0,1),(0,0)],输入(0,3)返回空列表,符合逻辑。
内容的提问来源于stack exchange,提问作者Rain
相关产品推荐
相关产品推荐

