Home Articles

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

Asked
Viewed 1497 times
5

尝试创建一个从列表中删除重复项的函数,并将其替换为单个元素 . 继续收到错误消息“函数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 Answers

  • 11

    正如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)
    
  • 5

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

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

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

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

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

Related