2014-06-22 90 views
1

即时比较新的哈斯克尔(第三天学习语言),并有模式匹配的问题。我已经在下面定义了函数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] 

回答

5

的问题是在第三模式:

doubleEveryOther (_:[xs]) 

该图案具有两个元素的列表的情况下,匹配(因为x:[xs]相当于[x,xs])。正确的语法是:

doubleEveryOther (_:xs) 
+0

明白了。我目前有空的模式,1和2,但不是2或更多。将其更改为上述模式可以为空,1和2或更多。谢谢。你有什么想法,为什么警告是包含第二种模式而不是第三种(第3行而不是第4种)?我一直在使用警告消息纠正我的代码问题,这可能是一个很大的因素。 – Dave0504

+0

@ Dave0504我认为这只是指模式匹配的第一行。请注意,在GHC警告中,它给出了整个范围:(3,1) - (5,55) – Benesh

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 

你可能也想在这种情况下,递归调用。

+0

谢谢李,非常感谢。 – Dave0504