Haskell实现match函数时出现Non-exhaustive patterns错误的技术问询
解决Haskell
match 函数的非穷尽模式问题 咱们先拆解下你遇到的问题:当第一个字符串是有限长度(比如replicate 21 'a'),第二个是无限长度的列表(比如repeat 'a')时,递归到第一个字符串耗尽变成[],但第二个字符串还剩无限多元素,这时候你的代码里完全没覆盖这种情况——你只写了match [] []和match [] [y],但[]和任意非空列表(包括无限长的(_:_))的组合没有对应的匹配模式,所以触发了*Non-exhaustive patterns*错误。
遗漏的模式分析
按照题目要求,当第一个字符串是第二个的前缀时要返回Nothing,而你遗漏了最关键的一种前缀场景:第一个列表为空,第二个列表是非空列表(不管有限还是无限)。
另外,你写的单元素列表匹配模式其实是冗余的,它们可以被通用的列表模式(x:xs)和(y:ys)覆盖,咱们可以简化代码结构。
修正后的完整代码
match :: String -> String -> Maybe Char -- 两个列表都为空,返回Nothing match [] [] = Nothing -- 第一个列表为空,第二个非空(前缀情况),返回Nothing match [] (_:_) = Nothing -- 第二个列表为空,第一个非空,返回第一个剩余字符 match (x:_) [] = Just x -- 两个列表都非空时递归处理 match (x:xs) (y:ys) | x == y = match xs ys | otherwise = Just x
测试验证
现在再跑之前出错的用例:
main> match (replicate 21 'a') (repeat 'a') Nothing
结果符合要求,因为第一个字符串是第二个的前缀。
再验证你之前的正确用例:
main> match "apple" "aple" Just 'p'
结果依然正确。
额外测试几个边界场景:
match "" "hello"→Nothing(前缀情况)match "hello" ""→Just 'h'(第一个非空第二个空)match "abc" "abd"→Just 'c'(首个不同字符)match "abc" "abc"→Nothing(完全相同)
这样所有场景都被覆盖,不会再出现非穷尽模式的错误了。
内容的提问来源于stack exchange,提问作者BeanieBarrow
相关产品推荐
相关产品推荐

