you - Haskell rango de notación para generar lista. Salida inesperada
pattern matching list haskell (2)
Básicamente porque el estándar así lo especifica. [e1, e2 .. e3]
desugars a enumFromThenTo e1 e2 e3
En la sección 6.3.4, el informe Haskell ''98 dice:
La secuencia enumFromThenTo e1 e2 e3 es la lista [e1, e1 + i, e1 + 2i, ... e3], donde el incremento, i, es e2-e1. Si el incremento es positivo o cero, la lista termina cuando el siguiente elemento sería mayor que e3; la lista está vacía si e1> e3. Si el incremento es negativo, la lista termina cuando el siguiente elemento sería menor que e3; la lista está vacía si e1 <e3.
El siguiente elemento nunca es mayor que 2.
Me encontré con un ejercicio en una de mis conferencias que me dejó confundido en la salida de [2, 2 ... 2]. Por qué al ingresar [2, 2 .. 2] se genera una lista "infinita" con 2.
La forma en que entendí la notación fue que el primer elemento es el límite de inicio, el segundo el "espacio" entre los números y el último es el final de la lista, en otras palabras, se detiene al alcanzar ese número.
Si mi razonamiento es correcto, ¿por qué la expresión [2, 2 .. 2] no da salida [2]? .
Pensé que Haskell podría evaluarlo de esta manera;
- Al imprimir el primer elemento de la lista es igual al último, por lo tanto, deténgase.
- O, si el primer elemento no se compara con el límite "externo", entonces la salida sería [2, 2] porque al agregar cero al número anterior (en caso de que el límite inicial 2) hubiéramos llegado al final y por lo tanto parar.
Obviamente no entiendo correctamente el funcionamiento de la notación, entonces, ¿cómo evalúa Haskell la expresión?
La notación pretende imitar la forma habitual de escribir secuencias matemáticas simples. El segundo elemento no es el paso, sino el segundo elemento real de la lista. El resto se extrapola linealmente desde allí. Ejemplos:
[1,2..10] = [1,2,3,4,5,6,7,8,9,10]
[1,3..10] = [1,3,5,7,9]
[4,3..0] = [4,3,2,1,0]
[0,5..] = [0,5,10,15,20,25,30,35... -- infinite
[1,1..] = [1,1,1,1,1,1,1,1,1,1,1... -- infinite
La razón por la que [2,2..2]
es infinita es porque ningún valor de la lista es mayor que el punto final correcto, que es la condición de terminación. Si desea que el paso sea 2, debe escribir [2,4..2]
, que da el resultado esperado [2]
. (Así que supongo que no es el segundo elemento real de la lista en todos los casos, pero ve la lógica)