Pregunta Perplejo por cómo este código es procesado por la instalación de Layout de Haskell


Mientras navega https://wiki.haskell.org/IO_inside, Encontré el siguiente comentario y código ...

"Además, las reglas de diseño de Haskell nos permiten usar el siguiente diseño:

main = do a <- readLn
          if (a>=0) then return ()
            else do
          print "a is negative"
          ...

eso puede ser útil para escapar del medio de una declaración de "hacer" larga. "

A partir de ahora, usaré el símbolo C * para referirme al código anterior.

Supongo que la intención de C * es leer en un número, y luego:
(i) Si no es negativo, no haga nada.
(ii) Si es negativo, muestre el resultado indicando que sí lo es.

Mi reacción inicial fue pensar que C * o bien no se analizaría correctamente o no se comportaría como se esperaba.

Pensé que Layout insertaría un conjunto vacío de llaves y un punto y coma inmediatamente después del segundo 'do' porque el lexema 'imprimir' no está sangrado más que el nivel de sangría del contexto de disposición actual establecido por 'a' en "a < - readLn ".

Es decir, mi predicción para el código insensible al diseño (en lo sucesivo, denominado C ') generado por Layout sería algo así como:

main = do {
          a <- readLn;
          if (a>=0) then return ()
            else do {};
          print "a is negative"
          ...
          }

Que yo pensé que este sería el caso, se basó en la siguiente frase contenida en la sección 2.7 ('Estructura léxica': 'Diseño') de la Parte 1 del Informe del lenguaje Haskell 2010 (https://www.haskell.org/onlinereport/haskell2010/haskellpa1.html)

"Si la sangría del lexema sin corchete inmediatamente después de where, let, do o es menor o igual que el nivel de sangría actual, en lugar de comenzar un diseño, se inserta una lista vacía" {} "y el diseño el procesamiento ocurre para el nivel actual (es decir, inserte un punto y coma o un corsé cerrado) ".

En la sección 10.3 ('Referencia de sintaxis': 'Diseño') de la Parte 1 (URL dada anteriormente) se proporciona una descripción más detallada de las reglas de diseño en Haskell 2010 Language Report.

Al leer esta cuenta más detallada, me sentí seguro de que mi predicción para el código insensible al diseño generado por Layout (es decir, C ') era correcta.

Sin embargo, para mi sorpresa, cuando probé el código original estipulado anteriormente (es decir, C *) en GHCi, funcionó (se analizó correctamente y se comportó como se esperaba).

Preguntas ...

  1. ¿Es correcta la oración que cité arriba (de la sección 2.7)?

  2. ¿Es precisa la cuenta detallada de las reglas de diseño mencionadas anteriormente (de la sección 10.3)?

  3. ¿Cuáles son las fallas en el razonamiento que empleé para llegar a mi predicción para el código insensible al diseño (es decir, C ') generado por Layout para el código original C *?

  4. ¿Cuál es el código insensible al diseño producido por Layout para el código original estipulado anteriormente (es decir, para C *) y cuáles son las reglas / principios que lo explican?

  5. En general, ¿hay alguna manera de que pueda ver el código insensible al diseño generado por Layout? Si es así, ¿qué es (por favor detalla / explica la técnica a un nivel adecuado para alguien nuevo en Haskell, como yo)?


32
2018-02-04 13:31


origen


Respuestas:


Esto es un desviación conocida y documentadade GHC del estándar Haskell en modo predeterminado o Haskell 98.

GHC tiene una extensión de lenguaje llamada NondecreasingIndentation que se puede usar para desencadenar este comportamiento. Si está habilitado, a do palabra clave presenta un nuevo bloque incluso si el siguiente token se inicia en el mismo nivel de sangría que el bloque circundante.

Si no quiere esto, diga cualquiera -XNoNondecreasingIndentation o -XHaskell2010 (o utilice pragmas de lenguaje en consecuencia).

Puede ver una versión bastante impresa del código que GHC analizó pasando el -ddump-parsed bandera a GHC. Esto solo eliminará parcialmente el diseño (lo hace para do-blocks, pero por ejemplo, no para let), pero podría proporcionar pistas.


26
2018-02-04 14:59