如何解决Haskell guard语句出现`otherwise`输入解析错误问题
1. guard语句报错的原因
报错和guard语法本身无关,是上一行代码存在两个语法错误,导致解析器无法识别表达式边界,触发otherwise位置的解析错误:
- 括号未闭合:两个
take调用的第一个参数都缺少闭合右括号,例如take ((div (length ys 2)) ys中左括号数量远多于右括号,表达式没有正确闭合,解析器会把下一行的otherwise当成当前表达式的一部分,自然报错。 - 函数调用参数错误:
div是二元函数,你写的div (length ys 2)参数格式完全错误,正确写法为div (length ys) 2。
补充说明:你后续替换的可运行if版本也存在逻辑冗余问题,ys !! 0是取字符串的第一个字符,对单个字符调用length属于无效逻辑,只是碰巧没有打断语法解析而已。
修复后的guard版本可正常运行:
palindromeHalfs :: [String] -> [String] palindromeHalfs xs = map firstHalf (filter palindrome xs) where firstHalf :: String -> String firstHalf ys | even len = take (len `div` 2) ys | otherwise = take (len `div` 2 + 1) ys where len = length ys palindrome :: String -> Bool palindrome str = str == reverse str
2. 两类写法的选择建议
这类多条件分支的场景更推荐使用guard语句:
- 当分支数量≥2时,guard的垂直对齐写法可读性远高于冗长的
if then else嵌套,代码更简洁,符合Haskell的声明式编码风格。 - 扩展性更强,后续如果需要新增判断条件,直接加新的guard分支即可,不需要修改原有结构。
只有简单的单个二分支逻辑时二者差异不大,可根据个人习惯选择。
内容的提问来源于stack exchange,提问作者jvkloc
相关产品推荐
相关产品推荐

