2011-02-16 21 views
22

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] genera una lista "infinita" con 2's.Haskell notación de rango para generar una lista. Resultado inesperado

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, es decir, se detiene al llegar a ese número.

Si mi razonamiento es correcto, ¿por qué la expresión [2, 2 .. 2] no muestra [2]?.


Pensé que Haskell podría evaluarlo de esta manera;

  1. Cuando se imprime el primer elemento de la lista es igual a la pasado, por lo tanto, detener.
  2. O, si el primer elemento no se compara con el límite "externo", la salida sería [2, 2] porque al agregar cero al número anterior (en el caso del inicio 2) habría llegado al final y, por lo tanto, se detendría.

que, obviamente, no comprender el funcionamiento de la notación correctamente, así que ¿cómo se evalúa la expresión Haskell?

+0

@ Robert Harvey, tengo curiosidad por qué revirtió las etiquetas. Esa notación es más conocida como notación de rango, y 'punto-dot-notación' era una nueva etiqueta. Puedo ver un posible razonamiento para volver a agregar la etiqueta 'dot-dot-notación', pero no puedo entender por qué eliminaría la etiqueta' range'. – luqui

+0

@luqui: 'range' puede significar cualquier cosa.Cambié la etiqueta a 'range-notation' y agregué una etiqueta wiki. –

Respuesta

33

La notación está destinada a imitar la forma habitual de escribir secuencias simples de matemáticas. El segundo elemento no es el paso, sino el segundo elemento real de la lista. El resto se extrapola linealmente de 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 [2,2..2] es infinito es porque no tiene valor de la lista es cada vez mayor que el extremo derecho, que es la condición de terminación. Si desea que el paso sea 2, debe escribir [2,4..2], que da la salida esperada [2]. (Así que supongo que no es el segundo elemento real de la lista en todos los casos, pero ve la lógica)

+1

Ese excelente amigo, gran explicación, especialmente; * "es infinito porque ningún valor de la lista es ** mayor ** que el punto final derecho" *, que es lo que principalmente me confundió. Todo lo mejor – Carlos

+0

Esta fue la clave para que lo entendiera: "Si quieres que el paso sea 2, debes escribir [2,4..2]". Comience con dos, suba linealmente pero deténgase antes de que el siguiente elemento sea mayor que 2, que sucede después de solo 1 elemento. –

26

Básicamente porque el estándar así lo especifica. [e1, e2 .. e3] desugars a enumFromThenTo e1 e2 e3

En section 6.3.4 the Haskell '98 informe 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 finaliza cuando el siguiente elemento sea mayor que e3; la lista está vacía si e1> e3. Si el incremento es negativo, la lista finaliza cuando el siguiente elemento sea menor que e3; la lista está vacía si e1 < e3.

El siguiente elemento es no mayor que 2.

+0

+1 por respuesta bien fundamentada –

Cuestiones relacionadas