recursive guardas functions else argument haskell syntax guard-clause pattern-guards

guardas - lambda haskell



¿Qué hace una coma en la sintaxis de guardia? (2)

En una base de código que estoy leyendo, encontré una declaración de función como esta (faltan algunas partes):

filepathNormalise :: BS.ByteString -> BS.ByteString filepathNormalise xs | isWindows, Just (a,xs) <- BS.uncons xs, sep a, Just (b,_) <- BS.uncons xs, sep b = ''/'' `BS.cons` f xs

¿Qué hace la coma aquí?

(Solo como beneficio adicional, si alguien lo sabe fácilmente: ¿se menciona esta sintaxis en la Programación de Haskell desde los primeros principios , y si es así, dónde? Como no puedo recordar haber leído sobre esto).


Esta sintaxis no es legal en Haskell ''98; esto se agregó a la especificación de lenguaje en Haskell 2010. Es parte de la extensión de lenguaje "protectores de patrones".

https://prime.haskell.org/wiki/PatternGuards

La verdadera utilidad de esto es que le permite hacer un patrón de coincidencia dentro de una cláusula de protección. El cambio sintáctico también tiene el efecto secundario de permitirle unir varios términos booleanos mediante comas.

(Personalmente, realmente no me gusta esta extensión, y estoy un poco sorprendido de que haya llegado a las especificaciones oficiales, pero ahí estamos ...)


Los guardias se describen en la sección 3.13 de Haskell 2010, Expresiones de casos (esa sección trata de expresiones de casos, no de declaraciones de nivel superior, pero presumiblemente la semántica es la misma):

guards → | guard1, …, guardn (n ≥ 1) guardpat <- infixexp (pattern guard) | let decls (local declaration) | infixexp (boolean guard)

Para cada expresión protegida, los guardias separados por comas se prueban secuencialmente de izquierda a derecha. Si todos ellos tienen éxito, entonces la expresión correspondiente se evalúa en el entorno extendido con los enlaces introducidos por los guardias. Es decir, los enlaces que se introducen por una guarda (ya sea mediante una cláusula let o una guarda patrón) están dentro del alcance de las siguientes guardas y la expresión correspondiente. Si alguno de los guardias falla, entonces esta expresión protegida falla y se prueba la siguiente expresión protegida.

En el caso simple, la coma sirve un rol similar a Boolean y . Pero la coma es más poderosa porque cada guardia puede introducir nuevos enlaces que son utilizados por las guardias subsiguientes (procediendo de izquierda a derecha).

Las comas en los guardias son lo suficientemente infrecuentes (en mi experiencia, al menos) como para describir esta característica como una trivialidad de Haskell; no es en absoluto necesaria para escribir (o, en su mayor parte, leer) Haskell. Sospecho que la programación de Haskell desde los primeros principios la omite por esa razón.