Haskell模式匹配警告

时间:2014-06-22 15:10:44

标签: haskell

我对Haskell相对较新(第三天学习语言)并且遇到模式匹配问题。我在下面定义了函数doubleEveryOther,据我所知,我已经涵盖了三种可能的场景:空列表,长度列表== 1和列表长度> 1.代码编译正常,但是当尝试使用该函数时,它会抛出一个非详尽的模式匹配错误:

*** Exception: ex2.hs:(3,1)-(5,55): Non-exhaustive patterns in function doubleEveryOther

然后我在GHCI中启用了警告,并在加载ex2.hs文件时发现以下警告:

ex2.hs:3:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for `doubleEveryOther':
        Patterns not matched: _ : (_ : (_ : _))

第3行:1指的是我认为我已用doubleEveryOther [] = []

覆盖的空案例

我无法看到我在哪里出错了。帮助赞赏。

干杯,

-- file: ex2.hs
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:[]) = [x]
doubleEveryOther (_:[xs]) = take (length [xs] - 1) [xs]

2 个答案:

答案 0 :(得分:5)

问题在于第三种模式:

doubleEveryOther (_:[xs])

此模式与具有两个元素的列表的情况相匹配(因为x:[xs]等同于[x,xs])。正确的语法是:

doubleEveryOther (_:xs)

答案 1 :(得分:4)

该行

doubleEveryOther (_:[xs]) = take (length [xs] - 1) [xs]

匹配一个双元素列表,即一个未绑定的头,后跟一个包含元素xs的单元素列表。你应该使用

doubleEveryOther (_:xs) = take (length xs - 1) xs

而不是take (n-1),您可以使用drop 1

doubleEveryOther (_:xs) = drop xs

或使用匹配:

(_:_:xs) = xs

在这种情况下,您可能还希望进行递归调用。