Haskell中判断列表为空并调用指定函数的实现问题
Haskell递归函数模式匹配问题修复
问题背景
我编写了一个接收两个字符串的Haskell函数qpFunc,通过递归遍历列表实现逻辑。需求是当第一个参数为空时,调用itWilcard函数处理第二个参数,但遇到两个问题:
- 尝试用模式匹配实现时,报错“Variable not in scope: ps :: [Char]”;
- 函数内的条件判断从未触发,调用
qpFunc "" "?"时出现“Non-exhaustive patterns in function qpFunc”错误。
已知x:xs不会匹配空列表,空列表的标准匹配模式是[],但不知道如何在空列表模式下正确调用指定函数。当前代码如下:
qpFunc :: String -> String -> (String, String) qpFunc [] [] = ("", "") qpFunc [] _ = itWilcard (p : ps) -- does not work qpFunc (s : os) (p : ps) | (s : os) == [] = itWilcard (p : ps) -- never reached ? | p == '*' = (os, p : ps) | p == '?' = qpFunc os ps | s == p = (os, ps) | otherwise = ([], "#")
错误原因
- 变量未定义错误:
qpFunc [] _ = itWilcard (p : ps)中,_是通配符,仅表示匹配任意值,但不会将其拆分为p:ps,直接使用未定义的p和ps自然会报错。 - 无效条件判断:
(s : os) == []永远不可能成立,因为(s:os)本身就是非空列表的模式(至少包含一个元素s),该条件逻辑冗余。 - 模式覆盖不全:现有模式仅覆盖了「两个参数都为空」「两个参数都非空」的情况,未处理「第一个参数为空、第二个非空」「第一个非空、第二个为空」的组合,导致调用
qpFunc "" "?"时触发非穷举模式错误。
修复方案
针对上述问题,调整模式匹配逻辑,覆盖所有输入组合,移除无效判断:
qpFunc :: String -> String -> (String, String) -- 两个参数都为空的情况 qpFunc [] [] = ("", "") -- 第一个参数为空,调用itWilcard处理第二个参数 qpFunc [] pat = itWilcard pat -- 第一个参数非空,第二个为空的情况 qpFunc (s : os) [] = ([], "#") -- 两个参数都非空的核心逻辑 qpFunc (s : os) (p : ps) | p == '*' = (os, p : ps) | p == '?' = qpFunc os ps | s == p = (os, ps) | otherwise = ([], "#")
关键调整说明
- 直接将空列表模式下的第二个参数完整传递给
itWilcard,无需强行拆分(若itWilcard仅接受非空列表,可单独拆分模式:qpFunc [] (p:ps) = itWilcard (p:ps),同时保留qpFunc [] []的分支)。 - 新增
qpFunc (s : os) []分支,覆盖第一个非空、第二个为空的场景,避免模式遗漏。 - 移除
(s : os) == []的无效判断,利用模式匹配本身区分空与非空列表。
内容的提问来源于stack exchange,提问作者Energizer1
相关产品推荐
相关产品推荐

