web-dev-qa-db-fra.com

Schémas de fonctionnement non exhaustifs

J'ai un problème avec ce code, il devrait compter la plus longue sous-chaîne de la même lettre dans une chaîne, mais il y a une erreur:

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

Je sais que c'est le problème des mauvais types, mais je ne sais pas où est l'erreur, ni comment la trouver ou la déboguer

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
25
kaz

Il semble que vous manquez le cas où il y a une liste d'un élément:

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

Voici un exemple artificiel similaire au vôtre:

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

Exemples:

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> 

Il réussit donc avec 0 et 2 éléments dans la liste, mais échoue lorsqu'il y a exactement un élément.


Notez que ce comportement n'est pas unique aux listes. Voici un exemple utilisant Maybe:

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

Exemples:

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

Cela est dû au fait qu'il existe deux constructeurs pour Maybe, Just <something> et Nothing. Nous n'avons pas fourni de cas pour Nothing, donc quand nous l'avons passé dans g, cela n'a pas fonctionné!


Consultez cette question et ses réponses pour plus d'informations sur l'obtention d'un peu d'aide du compilateur. J'ai suivi les conseils de la première réponse, et quand j'ai chargé mes exemples, c'est ce qui s'est passé:

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.

Cool! Le compilateur est assez intelligent!

41
Matt Fenwick

Le problème est que vous devez faire correspondre s'il reste 1 élément dans la récursivité, par exemple:

countLongest' n max (y:ys)

Parce que le premier correspond s'il reste 2 éléments ou plus et le dernier ne correspond que s'il n'y a plus d'élément.

4
glindste