I am trying to implement a function called compress such that if a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed. For example:
λ> compress "aaaabccaadeeee"
"abcade"
I have two solutions, compress and compress', that I thought are equivalent. However, compress' works while compress gives the error: "Non-exhaustive patters in function". I thought that compress will cover all cases, but I am not sure what went wrong. Thanks!
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"
Your pattern has two
:, meaning it only matches lists with 2 or more elements. You still need definitions for empty and singleton lists:The various guards are all only applied to lists matching the pattern used in the single definition you provide. (In particular, note that
null (x:ys)will never be true;nullonly returns true on[], not any list involving the:constructor.)In
compress', the irrefutable patternymatches any list not matched by pattern in the first definition.