首页 文章

功能中的非详尽模式[重复]

提问于
浏览
19

这个问题在这里已有答案:

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

*** 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 回答

  • 37

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

    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个元素成功,但是当只有一个元素时会失败 .


    请注意,此行为对于列表是唯一的 not . 这是使用 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.
    

    凉!编译器非常聪明!

  • 4

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

    countLongest' n max (y:ys)
    

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

相关问题