Haskell中compress函数非穷尽模式错误排查求助
解决Haskell compress函数的非穷举模式错误
你的compress函数报错的核心原因是模式匹配不完整:
你只给compress定义了compress (x:ys@(y:_))这一种模式,这个模式仅能匹配至少包含两个元素的列表(ys@(y:_)要求ys本身是非空的,意味着原列表至少有x和y两个元素)。当递归过程中遇到空列表[]或者单元素列表[x]时,没有对应的模式可以匹配,因此触发"Non-exhaustive patterns"错误。
再看你写的守卫条件:
null (x:ys)永远为False,因为x:ys是构造出来的非空列表,这个条件完全无效;null ys也永远为False,因为ys@(y:_)已经限定了ys是非空的,这个条件同样不会被触发。
而compress'能正常工作,是因为它额外定义了compress' ys = ys这个兜底模式,会匹配所有剩下的情况(空列表或单元素列表),补全了模式覆盖的所有可能性。
修正后的compress可以写成这样:
compress [] = [] compress [x] = [x] compress (x:ys@(y:_)) | x /= y = x : compress ys | otherwise = compress ys
或者更简洁的版本,和compress'逻辑一致:
compress (x:ys@(y:_)) | x == y = compress ys | otherwise = x : compress ys compress ys = ys
这样就覆盖了列表的所有可能情况:空列表、单元素列表、多元素列表,递归过程中就不会再出现模式匹配缺失的问题。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

