功能上的非详尽模式

时间:2011-12-08 18:11:13

标签: haskell pattern-matching non-exhaustive-patterns

我的代码有问题,它应该计算字符串中同一个字母的最长子字符串,但是有一个错误:

*** Exception: test.hs:(15,0)-(21,17): 
Non-exhaustive patterns in function countLongest'

我知道这是错误的类型问题,但我不知道错误在哪里,或者如何找到或调试它

countLongest :: (Eq a) => [a] -> Int
countLongest' :: (Eq a) => Int -> Int -> [a] -> Int

countLongest a = countLongest' 0 0 a
countLongest' n max (y:x:ys)
        | y == x = countLongest' (n+1) max (x:ys)
        | n > max = countLongest' 0 (n) (x:ys)
        | otherwise = countLongest' 0 (max) (x:ys)
countLongest' n max []
        | n > max = n
        | otherwise = max

2 个答案:

答案 0 :(得分:38)

看起来你错过了有一个元素列表的情况:

countLongest' n max (y:ys)
    | ... etc. ...
    | otherwise = ....

这是一个与你类似的人为例子:

f [] = 3         -- matches an empty list
f (a:b:bs) = 4   -- matches a list with at least two elements

示例:

Prelude> :load myfile.hs 
[1 of 1] Compiling Main             ( myfile.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [3]
*** Exception: myfile.hs:(3,0)-(4,13): Non-exhaustive patterns in function f

*Main> f []
3
*Main> f [1,2,3,4,5]
4
*Main> 

因此它在列表中以0和2个元素成功,但是当只有一个元素时会失败。


请注意,此行为对列表而言是唯一的。以下是使用Maybe的示例:

g :: Maybe x -> x
g (Just x) = x

示例:

*Main> g (Just 4)
4
*Main> g Nothing 
*** Exception: myfile.hs:6:0-13: Non-exhaustive patterns in function g

这是因为MaybeJust <something>Nothing有两个构造函数。我们没有为Nothing提供案例,因此当我们将其传递到g时,它无效!


查看this question及其答案,了解有关从编译器获得一些帮助的信息。我按照第一个答案的建议,当我加载我的例子时,这就是发生的事情:

prompt$ ghci -fwarn-incomplete-patterns

Prelude> :load myfile.hs 
[1 of 1] Compiling Main             ( myfile.hs, interpreted )

myfile.hs:3:0:
    Warning: Pattern match(es) are non-exhaustive
             In the definition of `f': Patterns not matched: [_]

myfile.hs:6:0:
    Warning: Pattern match(es) are non-exhaustive
             In the definition of `g': Patterns not matched: Nothing
Ok, modules loaded: Main.

酷!编译器非常聪明!

答案 1 :(得分:4)

问题是如果递归中还剩1个元素,则需要匹配,例如:

countLongest' n max (y:ys)

因为如果剩下2个或更多元素,第一个匹配,如果没有元素,则匹配最后一个匹配。