我正在尝试实现一个名为
compress
的函数,这样如果列表包含重复元素,则应将它们替换为该元素的单个副本。元素的顺序不应更改。例如:
λ> compress "aaaabccaadeeee"
"abcade"
我有两个解决方案,
compress
和compress'
,我认为它们是等效的。但是, compress'
有效,而 compress
给出错误:“函数中的非详尽模式”。我以为compress
会涵盖所有情况,但我不确定出了什么问题。谢谢!
compress (x:ys@(y:_))
| null (x:ys) = []
| null ys = [x]
| x /= y = x : compress ys
| x == y = compress ys
λ\> compress "aaaabccaadeeee"
Non-exhaustive patterns in function compress
compress' (x:ys@(y:_))
| x == y = compress' ys
| otherwise = x : compress' ys
compress' ys = ys
λ\> compress' "aaaabccaadeeee"
"abcade"
您的模式有两个
:
,这意味着它仅匹配具有 2 个或更多元素的列表。您仍然需要空列表和单例列表的定义:
compress [] = ...
compress [x] = ...
各种防护仅适用于与您提供的单个定义中使用的模式匹配的列表。 (特别要注意的是
null (x:ys)
永远不会为 true;null
仅在 []
上返回 true,而不是涉及 :
构造函数的任何列表。)
在
compress'
中,无可辩驳的模式 y
与第一个定义中的模式不匹配的任何列表匹配。