haskell pattern-matching non-exhaustive-patterns

haskell - Patrones no exhaustivos en función



pattern-matching non-exhaustive-patterns (2)

Esta pregunta ya tiene una respuesta aquí:

Tengo un problema con este código, debería contar la subcadena más larga de la misma letra en una cadena, pero hay un error:

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

Sé que es un problema de tipos incorrectos, pero no sé dónde está el error, ni cómo encontrarlo o depurarlo.

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


El problema es que debe coincidir si hay 1 elemento en la recursión, por ejemplo:

countLongest'' n max (y:ys)

Porque el primero coincide si quedan 2 o más elementos y el último solo coincide si no queda ningún elemento.


Parece que te estás perdiendo el caso donde hay una lista de un elemento:

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

Aquí hay un ejemplo artificial similar al tuyo:

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

Ejemplos:

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>

Entonces, tiene éxito con 0 y 2 elementos en la lista, pero falla cuando hay exactamente un elemento.

Tenga en cuenta que este comportamiento no es exclusivo de las listas. Aquí hay un ejemplo usando Maybe :

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

Ejemplos:

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

Esto sucedió porque hay dos constructores para Maybe , Just <something> y Nothing . No proporcionamos un caso para Nothing , así que cuando pasamos eso a g , ¡no funcionó!

Echa un vistazo a esta pregunta y sus respuestas para obtener información sobre cómo obtener un poco de ayuda del compilador. Seguí el consejo de la primera respuesta, y cuando cargué mis ejemplos, esto es lo que sucedió:

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.

¡Guay! El compilador es bastante inteligente!