2011-02-06 27 views
20

Estaba haciendo el 99 Problems in Haskell cuando encontré un solution en Problem 19 que no entendía del todo.Haskell (n + 1) en el patrón coincidente

La tarea es escribir una función de giro que funciona de la siguiente

*Main> rotate ['a','b','c','d','e','f','g','h'] 3 
"defghabc" 

*Main> rotate ['a','b','c','d','e','f','g','h'] (-2) 
"ghabcdef" 

Una solución aportada es

rotate [] _ = [] 
rotate l 0 = l 
rotate (x:xs) (n+1) = rotate (xs ++ [x]) n 
rotate l n = rotate l (length l + n) 

No entiendo cómo la coincidencia de patrones nunca puede llegar a la cuarta línea. Parece que tiene que ver con (n+1), por lo que cuando n es negativo, la tercera línea no coincide y, por lo tanto, se toma la cuarta. Si ese es el caso, ¿por qué funciona la notación (n+1)? ¿No es eso arbitrario o es una convención (en matemáticas?) de la que no tengo conocimiento?

Porque la forma en que lo entiendo es que rotar se llama recursivamente en la tercera línea con el argumento n reducido en uno. Así que creo que

rotate [] _ = [] 
rotate l 0 = l 
rotate (x:xs) n = rotate (xs ++ [x]) (n-1) 
rotate l n = rotate l (length l + n) 

es equivalente. Sin embargo, no lo es. Esta definición proporciona la siguiente advertencia

Warning: Pattern match(es) are overlapped 
     In the definition of `rotate': rotate l n = ... 

mientras que la anterior definición se compila muy bien.

Respuesta

26

Es un caso específico de lo que se llama "patrones n + k", que generalmente no le gusta, y will be has been removed from the language. Ver here para más información.

Here es una buena nota en n + k patrones, que cita el siguiente del Informe 98 Haskell (énfasis mío):

Coincidencia de un patrón n + k (donde n es un k variable y es un entero positivo literal) contra un valor v tiene éxito si x> = k, lo que resulta en la unión de n a x - k, y falla de lo contrario. De nuevo, las funciones> = y - están sobrecargadas, según el tipo de patrón. La coincidencia diverge si la comparación diverge.

La interpretación de la k literal es el mismo que en numéricos patrones literales, excepto que sólo se les permite número entero literales.

Así que la n+1 es sólo comparable si n es al menos 1, como se sospechaba. Su código alternativo elimina esta restricción, lo que resulta en coincidencias de patrón superpuestas.

+0

"Es un caso específico de lo que se llama" patrones n + k ", que generalmente no le gusta". Creo que la mejor solución podría haber sido la introducción de un tipo para los números naturales, que se puede utilizar para expresar * tamaño * y definir el patrón * n + 1 * en los productos naturales. Al carecer de este tipo en Haskell y en la mayoría de los lenguajes, como C/C++, vemos el esfuerzo de definir 'unsigned int',' size_t' (que es realmente natural bajo el capó) y problemas asociados de comparación entre el tipo firmado y sin signo, etc. los naturales, podemos hacer análisis de casos sobre el tamaño de las estructuras, que es bastante fundamental y fácil en Haskell. – tinlyx

Cuestiones relacionadas