¿cuál es el propósito de las flechas?

62

Estoy aprendiendo programación funcional con Haskell, y trato de captar conceptos entendiendo primero por qué los necesito.

Me gustaría saber el objetivo de las flechas en los lenguajes de programación funcionales. ¿Qué problema resuelven? Revisé enlace y enlace . Lo único que entiendo es que se utilizan para describir gráficos para cálculos y que permiten una codificación de estilo sin puntos más fácil.

El artículo asume que el estilo sin puntos es generalmente más fácil de entender y escribir. Esto me parece bastante subjetivo. En otro artículo ( enlace ), se implementa un juego de ahorcado, pero no puedo ver cómo hacen las flechas. Esta implementación natural.

Podré encontrar muchos artículos que describan el concepto, pero nada sobre la motivación.

¿Qué me estoy perdiendo?

    
pregunta Simon 17.10.2011 - 13:40

4 respuestas

41

Me doy cuenta de que llego tarde a la fiesta, pero has tenido dos respuestas teóricas aquí, y quería ofrecerte una alternativa práctica para masticar. Me referiré a esto como un noob de Haskell relativo que, sin embargo, recientemente ha sido sometido a la fuerza a través del tema de las flechas para un proyecto en el que estoy trabajando actualmente.

Primero, puedes resolver de manera productiva la mayoría de los problemas en Haskell sin llegar a las flechas. A algunos Haskellers notables realmente no les gustan y no los usan (vea aquí , aquí , y aquí para más información sobre esto). Entonces, si te estás diciendo a ti mismo "Oye, no necesito esto", entiende que realmente puedes estar en lo correcto.

Lo que encontré más frustrante acerca de las flechas cuando las aprendí por primera vez fue cómo los tutoriales sobre el tema alcanzaron inevitablemente la analogía de los circuitos. Si observa el código de Arrow, al menos la variedad azucarada, no se parece en nada a un lenguaje de definición de hardware. Sus entradas se alinean a la derecha, sus salidas a la izquierda y, si no las conecta correctamente, simplemente no se activarán. Pensé para mí mismo: ¿De verdad? ¿Es aquí donde hemos terminado? ¿Hemos creado un lenguaje tan completamente de alto nivel que una vez más consiste en cables de cobre y soldadura?

La respuesta correcta a esto, por lo que he podido determinar, es: En realidad, sí. El caso de uso del asesino ahora mismo para Arrows es FRP (creo que Yampa, juegos, música , y sistemas reactivos en general). El problema al que se enfrenta el FRP es, en gran medida, el mismo problema al que se enfrentan todos los demás sistemas de mensajería síncrona: cómo conectar un flujo continuo de entradas a un flujo continuo de salidas sin dejar caer información relevante o fugas. Puede modelar las secuencias como listas (varios sistemas FRP recientes utilizan este enfoque), pero cuando tiene muchas listas de entradas se hace casi imposible de administrar. Necesitas aislarte de la corriente.

Lo que permiten las flechas en los sistemas de FRP es la composición de las funciones en una red y al mismo tiempo abstrae por completo cualquier referencia a los valores subyacentes que pasan esas funciones. Si eres nuevo en FP, esto puede ser confuso al principio, y luego alucinante cuando has absorbido las implicaciones de ello. Solo recientemente absorbió la idea de que las funciones se pueden abstraer, y cómo entender una lista como [(*), (+), (-)] como de tipo [(a -> a -> a)] . Con las flechas, puedes impulsar la abstracción una capa más.

Esta capacidad adicional de abstraer conlleva sus propios peligros. Por un lado, puede llevar a GHC a los casos de esquinas donde no sabe qué hacer con sus supuestos de tipo. Tendrá que estar preparado para pensar en el nivel de tipos; esta es una excelente oportunidad para aprender sobre los tipos y los Tipos de Rango y otros temas similares.

También hay una serie de ejemplos de lo que yo llamaría "Stupid Arrow Stunts" donde el codificador alcanza un combinador de Arrow solo porque quiere mostrar un buen truco con tuplas. (Aquí está mi propia contribución trivial a la locura .) Siéntete libre ignorar este hot-dogging cuando lo encuentres en la naturaleza.

NOTA: Como mencioné anteriormente, soy un noob relativo. Si he promulgado algunos conceptos erróneos arriba, siéntase libre de corregirme.

    
respondido por el rtperson 09.11.2011 - 23:48
28

Esta es una especie de respuesta "suave", y no estoy seguro de que alguna referencia lo indique de esta manera, pero así es como he llegado a pensar en las flechas:

Un tipo de flecha A b c es básicamente una función b -> c pero con más estructura de la misma manera que un valor monádico M a tiene más estructura que un antiguo a .

Ahora, la estructura extra depende de la instancia de flecha en particular de la que estés hablando. Al igual que con las mónadas IO a y Maybe a , cada una tiene una estructura adicional diferente.

Lo que obtienes con las mónadas es la incapacidad de pasar de M a a a . Ahora, esto puede parecer una limitación, pero en realidad es una característica: el sistema de tipos lo protege de convertir un valor monádico en un valor antiguo simple. Solo puede hacer uso del valor participando en la mónada a través de >>= o las operaciones primitivas de la instancia de la mónada en particular.

Del mismo modo, lo que se obtiene de A b c es la incapacidad de construir una nueva "función" que consuma c y produzca b. La flecha le protege a usted de consumir el b y crea un c excepto al participar en los diversos combinadores de flecha o al usar las operaciones primitivas de la instancia de flecha en particular.

Por ejemplo, las funciones de señal en Yampa son aproximadamente (Time -> a) -> (Time -> b) , pero además tienen que obedecer una cierta restricción de causalidad : la salida en el momento t está determinada por los valores pasados de la entrada señal: no se puede mirar hacia el futuro Entonces, lo que hacen es que en lugar de programar con (Time -> a) -> (Time -> b) , programa con SF a b y construye sus funciones de señal a partir de primitivas. Sucede que como SF a b se comporta mucho como una función, de modo que la estructura común se denomina "flecha".

    
respondido por el Lambdageek 17.10.2011 - 23:17
14

Me gusta pensar que las flechas, como las mónadas y las funciones, permiten que el programador haga composiciones exóticas de funciones.

Sin mónadas o flechas (y funciones), la composición de funciones en un lenguaje funcional se limita a aplicar una función al resultado de otra función. Con las mónadas y los funtores, puede definir dos funciones y luego escribir un código reutilizable separado que especifique cómo esas funciones, en el contexto de la mónada en particular, interactúan entre sí y con los datos que se transfieren a ellas. Este código se coloca dentro del código de enlace de la Mónada. Por lo tanto, una mónada es una vista, solo un contenedor para el código de enlace reutilizable. Las funciones se componen de manera diferente dentro del contexto de una mónada de otra mónada.

Un ejemplo simple es la mónada Maybe, donde hay un código en la función de enlace tal que si una función A está compuesta con una función B dentro de una mónada Maybe, y B produce una Nothing, entonces el código de enlace asegurará que la composición de las dos funciones genera un Nothing, sin molestarse en aplicar A al valor de Nothing que sale de B. Si no hubiera una mónada, el programador tendría que escribir código en A para probar una entrada de Nothing.

Las mónadas también significan que el programador no necesita escribir explícitamente los parámetros que cada función requiere en el código fuente: la función de enlace maneja el paso de parámetros. Entonces, al usar mónadas, el código fuente puede comenzar a parecerse más a una cadena estática de nombres de funciones, en lugar de parecer que la función A "llama" a la función B con los parámetros C y D: el código comienza a parecer más un circuito electrónico que un Máquina en movimiento: más funcional que imperativa.

Las flechas también conectan funciones junto con una función de enlace, proporcionando funcionalidad reutilizable y ocultando parámetros. Pero las flechas pueden estar conectadas y compuestas, y opcionalmente pueden enrutar datos a otras flechas en tiempo de ejecución. Ahora puede aplicar datos a dos rutas de Flechas, que "hacen cosas diferentes" a los datos y volver a ensamblar el resultado. O puede seleccionar la rama de Flechas para pasar los datos, dependiendo de algún valor en los datos. El código resultante es incluso más parecido a un circuito electrónico, con interruptores, retrasos, integración, etc. El programa parece muy estático, y no debería poder ver mucha manipulación de los datos en curso. Hay menos y menos parámetros en los que pensar, y menos necesidad de pensar qué valores pueden tomar o no los parámetros.

La escritura de un programa con Flechas implica principalmente la selección de Flechas de estante como divisores, interruptores, retardos e integradores, las funciones de elevación en esas Flechas y la conexión de las Flechas para formar flechas más grandes. En la Programación reactiva funcional con flecha, las flechas forman un bucle, con la entrada del mundo combinada con la salida de la última iteración del programa, de modo que la salida reacciona a la entrada del mundo real.

Uno de los valores del mundo real es el tiempo. En Yampa, la flecha de función de señal invierte el parámetro de tiempo a través del programa informático; nunca se accede al valor de tiempo, pero si conecta una flecha integradora en el programa, generará valores integrados a lo largo del tiempo que luego puede usar para pasar a otras flechas.

    
respondido por el Robert Onslow 09.10.2012 - 13:28
3

Solo una adición a las otras respuestas: Personalmente, me ayuda mucho a comprender qué es tal concepto (matemáticamente) y cómo se relaciona con otros conceptos que conozco.

En el caso de las flechas, encontré útil el siguiente artículo: compara las mónadas, los funtores aplicativos (expresiones idiomáticas) y las flechas: Las idioms son ajenas, las flechas son meticulosas, las mónadas son promiscuas por Sam Lindley, Philip Wadler y Jeremy Yallop.

También creo que nadie mencionó este enlace que puede proporcionarle algunas ideas y publicaciones sobre el tema.

    
respondido por el Petr Pudlák 09.10.2012 - 20:32

Lea otras preguntas en las etiquetas

Comentarios Recientes

Mira ma, y agarra una flecha. ¿Por qué no tengo ese estúpido llamado así? Donde hay polvo, va a arder ... ¿Es belrrrrrd? - Vagabundea. Laboratorio de hechiceros, Capítulo 8 - ¡Señor! Caminando entre la tercera y la cuarta puerta, dando vueltas y mirando a través de ella, te das cuenta de que has sufrido daños en tu armadura y te faltan armas de arco, luego ves a una chica hula cayendo detrás de ti, comienza a llorar y ahora está cayendo. sobre ti, mientras los dos te apuntan hasta que estés seguro de... Lee mas