Haskell代码问题排查:寻找buildBoard函数中的无限循环
Haskell buildBoard函数问题排查(重点:无限循环)
无限循环的核心原因
问题出在getFirstNonNumber函数的递归调用语法错误:
getFirstNonNumber num = if xs!!num `elem` [',','/'] then num else getFirstNonNumber num+1
Haskell中函数调用优先级高于加法运算符,所以getFirstNonNumber num+1实际执行的是(getFirstNonNumber num) + 1,而非预期的getFirstNonNumber (num + 1)。这会导致递归时num值永远不会递增,只要当前位置的字符不是,或/,就会无限重复调用同一个num,触发无限递归。
其他潜在问题
- 越界访问风险:大量使用
head xs和xs!!1,但未检查字符串长度。当xs只剩单个字符时,xs!!1会直接抛出IndexOutOfBounds异常。 - 玩家类型错误:处理
'b'开头的字符时,错误构造了Piece White intConversion,应该是Piece Black intConversion。 - 数值转换的越界问题:
intConversion中,若getFirstNonNumber 0返回0,getFirstNonNumber 0 -1会得到-1,xs!!(-1)直接触发异常。 - 终止分支无效:
buildBoard' [] _ = [[]]几乎不会被触发,且返回的[[]]不符合Board(9行二维列表)的预期结构。
修复方案
- 修正
getFirstNonNumber的递归调用:getFirstNonNumber num = if xs!!num `elem` [',','/'] then num else getFirstNonNumber (num + 1) - 替换
head和!!为模式匹配,避免越界:
例如将多字符检查的分支改为模式匹配形式:buildBoard' (x:y:rest) result | x == ',' && y == ',' = buildBoard' (y:rest) (Empty:result) | x == '/' && y == ',' = buildBoard' (y:rest) (Empty:result) -- 其他双字符判断分支 buildBoard' (x:rest) result | x == 'w' = -- 处理逻辑 | x == 'b' = -- 处理逻辑 | x == '+' = buildBoard2 (reverse result) buildBoard' [] _ = error "Unexpected empty input" - 修正Black玩家的构造逻辑:
|head xs == 'b' = buildBoard' (drop (getFirstNonNumber 0) xs) (Piece Black intConversion : result) - 给
intConversion添加前置检查,确保getFirstNonNumber 0 > 1,避免越界访问。
内容的提问来源于stack exchange,提问作者Lewision1
相关产品推荐
相关产品推荐

