2011-10-04 10 views
7
test :: String -> String -> Int 

test' x y n = n 
test' "" (y:ys) n = error "error" 
test' (x:xs) "" n = error "error" 
test' (x:xs) (y:ys) n = 
     if  x == y 
     then test' xs ys n 
     else test' xs ys (n+1) 
test a b = test' a b 0 

Cuando compilo esto, me da este resultado:Haskell - Partido de patrón (es) se solapan

Warning: Pattern match(es) are overlapped 

Y la respuesta siempre es "0", que no es lo que pretendía. ¿Cuál es el problema con el código y cómo solucionarlo?

Respuesta

9

test' x y n = n coincidirá para cada llamada, los otros patrones no serán considerados. Creo que este caso debería ser test' "" "" n = n. Obtiene el mismo resultado si mueve su línea original al final (cuando fallan todos los demás casos), pero luego debe escribir test' _ _ n = n, lo que muestra que deliberadamente ignora algunos de los argumentos.

[Editar]

Una solución más corto sería:

test a b | length a == length b = sum $ map fromEnum $ zipWith (/=) a b 
     | otherwise = error "error" 

La expresión zipWith genera una lista de Bool que es True para cada diferencia. La función fromEnum asigna False a 0 y True a 1.

+0

¡Muy útil! ¡He aprendido mucho! Gracias – Ferry

7

Los patrones se prueban en orden. El primero de sus patrones para test' siempre coincide, por lo que siempre se usa. El primer caso probablemente sea

test' "" "" n = n 

en su lugar.

Cuestiones relacionadas