pattern - restricciones multiples haskell
Haskell(n+1) en la coincidencia de patrones (1)
Estaba haciendo los 99 Problemas en Haskell cuando encontré una solution al Problema 19 que no entendía completamente.
La tarea es escribir una función de rotación que funcione así.
*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 proporcionada 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 puede llegar a la cuarta línea. Parece que tiene que ver con el (n+1)
modo 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é la notación (n+1)
funciona de esa manera? ¿No es eso arbitrario o es una convención (en matemática) 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 pensaría 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 da la siguiente advertencia
Warning: Pattern match(es) are overlapped
In the definition of `rotate'': rotate l n = ...
mientras que la primera definición compila bien.
Es un caso específico de lo que se denomina "patrones de n + k", que generalmente no es de su agrado y se eliminará del idioma . Vea here para más información.
Here hay una buena nota sobre los patrones de n + k, que cita lo siguiente del Informe Haskell 98 (el énfasis es mío):
Hacer coincidir un patrón n + k (donde n es una variable y k es un literal entero positivo) con un valor v tiene éxito si x> = k , lo que resulta en el enlace de n a x - k, y falla de lo contrario. Nuevamente, las funciones> = y - están sobrecargadas, dependiendo del tipo de patrón. La coincidencia diverge si la comparación diverge.
La interpretación del literal k es la misma que en los patrones literales numéricos, excepto que solo se permiten los literales enteros.
Por lo tanto, n+1
solo coincide si n
es al menos 1, como sospechaba. Su código alternativo elimina esta restricción, lo que da como resultado coincidencias de patrones superpuestos.