例外:功能中的非详尽模式

时间:2013-08-01 01:48:22

标签: haskell functional-programming runtime-error

尝试创建一个从列表中删除重复项的函数,并用单个元素替换它们。继续收到错误消息“函数removedplicate中的非穷举模式”。我认为这意味着我的模式匹配缺少可能的情况?我想我已经涵盖了所有的可能性。我对Haskell很新,所以非常感谢任何帮助。

removeduplicate :: (Eq a) => [a] -> [a]
removeduplicate [] = []
removeduplicate (x:[]) = [x]
removeduplicate (x:z:[]) = if z == x then [x] else (x:z:[])
removeduplicate (x:y:[xs])
    | x == y = x:(removeduplicate [xs])
    | otherwise = x:y:(removeduplicate [xs])

2 个答案:

答案 0 :(得分:11)

您的问题是最终模式。我假设它是为了匹配所有列表,但是你拥有它的方式,它匹配一个列表,其中包含一个元素xs

这意味着编译器看到了3个元素列表的匹配,但没有看到任意长度列表的匹配,这就是它抱怨的原因。

要解决此问题,请移除xs周围的框。

removeduplicate (x:y:xs)
    | x == y = x:(removeduplicate xs)
    | otherwise = x:y:(removeduplicate xs)

现在xs被视为一个列表,因此您将列表与匹配至少三个项目,而不仅仅是三个项目。

答案 1 :(得分:5)

正如Matt Bryant所说,特定的编译器错误源于使用[xs]而不是xs

你实际上还有一个冗余模式:

removeduplicate (x:z:[]) if z == x then [x] else (x:z:[])

此行可以删除,因为类型x:y:[]的模式已由

处理
removeduplicate (x:y:xs)
    | x == y = x:(removeduplicate xs)
    | otherwise = x:y:(removeduplicate xs)

由于xs可以是空列表,removeduplicate []可以解析为[]

但请记住,您提供的代码最多只删除2个连续的重复元素。连续三次重复,将在结果中插入两个相同的元素,这可能不是您想要的。

更完整的功能可能如下所示:

removeduplicate []     = []
removeduplicate (x:xs) = x:(removeduplicate $ dropWhile (== x) xs)