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.
"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