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.