Haskell开发基础扫雷 isGoal函数报unexpected ;语法错误求助
报错根因
你遇到的Syntax error in expression (unexpected ';', possibly due to bad layout)并非isGoal函数本身写法错误,是isGoal上方的nextMyStates函数存在未闭合的括号,Haskell基于缩进的布局解析规则被破坏,解析器误将后续的isGoal代码识别为上一个函数的未完成片段,才抛出该语法错误。
逐处修正方案
1. 修复触发报错的nextMyStates及关联check函数
原代码存在三个核心问题:
- 多层
check嵌套后缺失大量闭合右括号 - 函数参数传递逻辑错误:
check第一个参数类型是MyState -> MyState(即up/down这类移动/操作函数),你误将函数执行结果作为第一个参数传入,且++列表拼接符被错误写在check调用括号内部 - 原
check的else分支返回值类型不匹配:f s是MyState类型,但check要求返回[MyState]列表类型,需要将结果包装为单元素列表,同时缺少非2个剩余地雷场景的通配匹配,会触发运行时模式匹配失败
修正后的代码:
check:: (MyState -> MyState) -> MyState -> [MyState] check f s = if f s == Null then [] else [f s] nextMyStates:: MyState -> [MyState] nextMyStates s = check up s ++ check down s ++ check left s ++ check right s ++ check collect s
2. 优化isGoal函数
原写法逻辑成立,但可以用Haskell的模式匹配更简洁实现,避免冗余的if判断:
isGoal :: MyState -> Bool isGoal (S _ [] _ _) = True isGoal _ = False
3. 修复其余语法/逻辑错误
search函数中调用isGoal、nextMyStates时,传入的S构造值需要用括号包裹为单个参数,原写法isGoal S l al d z会被解析为给isGoal传递5个参数,与函数类型签名不符;另外原BFS逻辑拼接队列的顺序有误,修正后:
search::[MyState]->MyState search (s@(S l al d z):xs) | isGoal s = s | otherwise = search (xs ++ nextMyStates s)
constructSolution函数中错误将z(MyState类型)当作函数调用,写了不存在的p cs s k参数,递归时直接传入z即可:
constructSolution :: MyState -> [String] constructSolution Null = [] constructSolution (S _ _ d z) = d : constructSolution z
solve函数中传入nextMyStates的S构造值同样需要用括号包裹为单个参数,修正后:
solve :: Cell->[Cell]->[String] solve start mines = constructSolution $ search [s0] where s0 = S start mines "" Null
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

