Haskell validateFEN函数空列表错误排查及代码优化简化
Haskell 9x9 FEN格式验证错误分析与优化实现
错误原因
你的代码抛出Prelude.head: empty list异常的核心问题是递归缺少终止条件:
help3函数会持续递归处理剩余字符串,直到字符串被耗尽。但最后一行的FEN片段没有结尾的/,当递归到最后一次调用时,drop 8 b会返回空列表,此时调用head函数自然触发空列表异常。- 原逻辑错误假设每9个字符(8个
,加1个/)为一组,但最后一行不存在结尾的/,导致递归到后期剩余字符串长度不足9,drop8 b为空,head无法处理空输入。
简洁实现方式
核心思路是直接验证FEN的结构规则:必须分割为9行,每行分割为9列。以下是更直观且健壮的实现:
第一步:实现基础分割函数(无需额外依赖)
如果不想引入第三方split包,可以自己实现字符串分割函数:
splitOn :: Eq a => a -> [a] -> [[a]] splitOn c s = case break (== c) s of (prefix, _:suffix) -> prefix : splitOn c suffix (prefix, []) -> [prefix]
第二步:实现验证函数
validateFEN :: String -> Bool validateFEN fen = let rowSegments = splitOn '/' fen -- 校验是否正好9行 correctRowCount = length rowSegments == 9 -- 校验每行分割后正好9列 correctColumnCount = all (\row -> length (splitOn ',' row) == 9) rowSegments in correctRowCount && correctColumnCount
测试示例FEN
sampleFEN = ",w84,w41,w56,w170,w56,w41,w84,/,,w24,w40,w17,w40,w48,,/,,,w16,w16,w16,,,/,,,,,,,,/,,,,,,,,/,,,,,,,,/,,,b1,b1,b1,,,/,,b3,b130,b17,b130,b129,,/,b69,b146,b131,b170,b131,b146,b69," -- 调用验证函数 validateFEN sampleFEN -- 返回True
如果可以使用第三方包,直接导入Data.List.Split的splitOn函数即可,代码会更简洁。
内容的提问来源于stack exchange,提问作者Snusqx
相关产品推荐
相关产品推荐

