A todos nos encanta do
, y tenía curiosidad si quizás este tipo de sintaxis alternativa teóricamente sería útil fuera del mundo de la mónada. Si es así, ¿qué otro tipo de cálculos simplificaría? ¿Tendría sentido tener algo equivalente para Applicative, por ejemplo?Haskell: ¿Sería útil la notación "do" para contextos distintos de las mónadas?
Respuesta
Podría ser útil tener en cuenta, con respecto a la notación do
en sí misma, para qué es en realidad bien para. Como señala Travis Brown, anteriormente he abogado por el uso de un estilo de "aplicación de funciones" con Monad
sy tipos relacionados, pero también hay otra cara: Algunas expresiones simplemente no se pueden escribir limpiamente en función directa estilo de aplicación. Por ejemplo, la siguiente puede hacer rápidamente estilo aplicativo torpe:
- intermedio utilizado en múltiples subexpresiones, a diferentes profundidades de anidación
- argumentos de la función más externa utilizados están anidadas en subexpresiones
- torpe o inconsistentes orden de argumento, es decir, necesidad de aplicar parcialmente una función a algo que no sea su primer argumento
- Control de flujo profundamente integrado basado en resultados intermedios, con subexpresiones compartidas entre ramas
- Coincidencia de patrón o n resultados intermedios, en particular en el caso de la extracción de parte de un resultado, utilizando que para más de cálculo, a continuación, la reconstrucción de una versión modificada como el siguiente resultado
Escritura de una función tal como una sola expresión requiere generalmente o bien múltiples lambdas anidados , o el tipo de absurdo que ofusca las tonterías que dan un mal nombre al estilo sin puntos. Un bloque do
, por otro lado, proporciona azúcar sintáctico para un alcance anidado fácil de resultados intermedios con flujo de control incorporado.
Lo normal sería, probablemente, extracto de este tipo subexpresiones y los pone en una cláusula where
o algo, pero ya que los valores normales forman una mónada con aplicación de función como (>>=)
--namely la Identity
mónada - que concebiblemente podría escribir una función de este tipo de un bloque de do
en su lugar, aunque la gente podría verte gracioso.
Además del material de alcance/unión, la otra cosa que un bloque de do
hace por usted es elide el operador que las cadenas de subexpresiones juntos. No es demasiado difícil imaginar otros casos en los que sería bueno tener una notación para "combinar estas expresiones usando esta función dentro de este bloque", y luego dejar que el compilador complete los espacios en blanco.
En el caso fácil, donde todas las expresiones tienen el mismo tipo, ponerlas en una lista y luego plegarlas funciona bien, construyendo cadenas de esta manera usando unwords
y unlines
, por ejemplo. El beneficio de do
es que combina expresiones con estructura común y tipos compatibles, pero no idénticos.
De hecho, el mismo principio general se puede decir de la notación "soporte de lenguaje" de la Applicative
papel: ¿Dónde do
bloques utilizan saltos de línea para eludir construcción monádico, soportes modismo utilizan yuxtaposición a eludir aplicación de función levantada. La notación proc
para Arrow
es también similar, y otros conceptos se podría expresar limpiamente de tal manera, así, por ejemplo:
- Composición estructuras de datos, por ejemplo, la fusión de los conjuntos de resultados de algún tipo, elidiendo la función de combinación de
- Otros lenguajes de aplicación funcionan, como el estilo "tubería hacia adelante" argumento de la primera, elidiendo el operador aplicación
- cálculos paralelos, elidiendo la función de agregación resultado
Aunque no es demasiado difícil hacer muchos de estos ya sea en un solo tipo o en una instancia completa de Monad
, sería bueno tener un trozo de azúcar sintáctico unificado y extensible para el concepto general. Ciertamente hay un hilo común atando todo esto y más, pero eso es un tema mucho más grande en realidad no relacionados con la sintaxis ...
Hay un preprocesador de GHC de hacer eso para Flechas: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/arrow-notation.html
Applicative
tiene (mucho más limitado, y más compacto) Idiom soportes, consulte Applicative Programming with Effects, Strathclyde Haskell Medio Ambiente de la página 4. Conor McBride ha implementado estos , Creo.
No veo cómo generalizar este tipo de sintaxis especiales, pero tal vez no lo he pensado lo suficiente.
Mi sensación es que many Haskell programmers don't love do
en absoluto, y uno de los argumentos comunes en favor del uso de Applicative
cuando no se necesita toda la potencia de Monad
es que los combinadores <$>
, <*>
, etc. permiten una muy clara y concisa estilo de codificación.
Incluso para el código monádico, muchas personas prefieren utilizar =<<
explícitamente en lugar de do
notación. camccann 's answer to your previous question about <*>
da un argumento fantástico para esta preferencia.
Tiendo a escribir mis primeros borradores usando do
y luego lo reemplazo con combinadores mientras reviso. Esto es solo una cuestión de mi propia experiencia y gusto: a menudo es más fácil para mí bosquejar las cosas de una manera más imperativa (que es más conveniente con do
), pero creo que el código no do
suele ser más bonito.
Para las flechas, por otro lado, no puedo imaginar no usar proc
y command do
. Las tuplas se vuelven tan feas tan rápido.
La notación do
es básicamente una forma de decir "transformar a lambdas según sea necesario y distribuir >>=
entre las líneas".
Cuando es obvio qué operador se está utilizando para enrollar todo, es bueno omitir y aprovechar el operador de "nueva línea".
La nueva línea programable sería una buena manera de acercarse a la lista de makings, cadenas de aplicaciones, & c. Para hacer listas, también necesitaría un "outdent programable". En realidad, sólo podría llevar a los tres bits de significativas y hacer que todos sobrecargable:
- Begin de
do
. - Entre
do
s. - Fin de
do
.
Entonces probablemente ya no deberías llamarlo do
. Tal vez debería ser solo un soporte.
Los paréntesis idiomáticos forman una buena manera de pensar acerca de los aplicativos, pero no son la única extensión de sintaxis posible.
Philippa Cowderoy publicó una propuesta de "Applicative do" notación para el Haskell-café hace un tiempo con la observación de que cualquier función que se ve algo así como:
foo = do
x <- bar
y <- baz
quux y 1234 x
donde las variables ligados por <-
sólo se producen en el la última línea podría implementarse con Applicative - De hecho, implementé una macro basada en reglas de sintaxis para este esquema, que llamé 'ado'.
Esto es útil en los casos en que el orden de los efectos aplicativos difiere de la "orden natural" y asumir la existencia de 'preámbulos' en Haskell acaba desugar a:
foo = (\x y -> quux y 1234 x) <*> bar <*> baz
Sin embargo, el ámbito léxico las reglas son un poco desconcertantes.
Hay una generalización de las mónadas que encaja con do
notación - mónadas parametrizada. Ver Beyond Monads por sigfpe. Ejemplo de uso:
test1' = do put 1
x <- get
put (show x)
y <- get
return (x,y)
Esta es una "mónada estado" que almacena primero un número, y luego una cadena.
BlazeHtml está utilizando do
-notation cuando en realidad es sólo una Monoid
(aunque envuelto como un Monad
para poder utilizar do
).
Así que una notación similar para Monoid
s sería útil allí.
Si nos fijamos en el código de mi juego "Defend The King", entonces también hago un montón de mconcat
ing, y como BlazeHtml, me beneficiaría de una sintaxis bonita para eso.
- 1. Reingresando notación para mónadas indexadas
- 2. Scala equivalente de do-notación de Haskell (una vez más)
- 3. Cómo escribir sin la notación do
- 4. Scala equivalente a las mónadas de Haskell
- 5. Mezcla de mónadas en Haskell
- 6. Algunas preguntas sobre las mónadas en Haskell
- 7. ¿OpenGL es seguro para múltiples hilos con contextos distintos?
- 8. ¿Hay una clase de "unidad"? ¿Sería útil?
- 9. evaluación de Haskell y perezosas Mónadas
- 10. ¿Cuándo sería útil un flip-flop Ruby?
- 11. Notación de suma en Haskell
- 12. Escribir loops para IO interactiva: problemas con notación de do y diseño
- 13. Haskell notación de rango para generar una lista. Resultado inesperado
- 14. ¿Son las continuas mónadas?
- 15. ¿Cuál es la alternativa de las mónadas para usar IO en la programación funcional pura?
- 16. ¿Cuál es el propósito de "do!" notación en F #?
- 17. ¿Qué tan útil sería heredar constructores en C++?
- 18. Mónadas Haskell y un fallo que no requiere una cadena
- 19. Contextos para Emacs
- 20. ¿Qué diablos es ReverseHTTP y por qué sería útil?
- 21. ¿Cuáles son todas las convenciones de nomenclatura de mónadas?
- 22. ¿Cuál es el estado actual de las mónadas restringidas?
- 23. donde la cláusula `where` es útil en Haskell
- 24. Mónadas como adjuntos
- 25. Reempazar mónadas: ¿una forma genérica?
- 26. "<-" enlaces en notación
- 27. Algunos lenguajes y usos para mónadas
- 28. Construcciones de cálculo (Mónadas, Flechas, etc.)
- 29. Sintaxis Haskell para una expresión de caso en un bloque do
- 30. ¿Cree que "la aplicación automática de interfaz" sería útil en .NET/C#
Hombre, me siento un poco mal - usted tiene más del doble de los votos por aquí e incluso se vinculó a una de mis respuestas anteriores, pero mi respuesta fue aceptada en su lugar ... por lo que vale, de todo corazón apruebo esto ¡responder! –