Home Articles

Haskell模式匹配警告

Asked
Viewed 1926 times
1

我对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 Answers

  • 5

    这条线

    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
    

    在这种情况下,您可能还想进行递归调用 .

  • 4

    问题出在第三种模式:

    doubleEveryOther (_:[xs])
    

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

    doubleEveryOther (_:xs)
    

Related