Eu percebo que estou chegando atrasado para a festa, mas você teve duas respostas teóricas aqui, e eu queria fornecer uma alternativa prática para mastigar. Eu estou chegando a isso como um noob Haskell relativo que, no entanto, foi recentemente forçado através do assunto Arrows para um projeto no qual estou trabalhando atualmente.
Primeiro, você pode resolver de maneira produtiva a maioria dos problemas em Haskell sem usar as setas. Alguns notáveis Haskellers genuinamente não gostam e não os usam (veja aqui , aqui e aqui para saber mais sobre isso). Então, se você está dizendo para si mesmo "Ei, eu não preciso disso", entenda que você pode realmente estar correto.
O que eu achei mais frustrante sobre as setas quando as aprendi foi como os tutoriais sobre o assunto inevitavelmente alcançaram a analogia dos circuitos. Se você olhar para o código Arrow - a variedade açucarada, pelo menos - não se parece muito com uma linguagem de defnição de hardware. Suas entradas se alinham à direita, suas saídas à esquerda e, se você não conseguir conectá-las corretamente, elas simplesmente não disparam. Eu pensei comigo mesmo: Realmente? É aqui que acabamos? Já criamos uma linguagem tão completamente de alto nível que mais uma vez consiste em fios de cobre e solda?A resposta correta para isso, até onde eu consegui determinar, é: Na verdade, sim. O caso de uso matador agora para Arrows é FRP (pense em Yampa, jogos, música e sistemas reativos em geral). O problema enfrentado pelo FRP é basicamente o mesmo problema enfrentado por todos os outros sistemas de mensagens síncronas: como conectar um fluxo contínuo de entradas em um fluxo contínuo de saídas sem descartar informações relevantes ou vazamentos de informações. Você pode modelar os fluxos como listas - vários sistemas recentes de FRP usam essa abordagem - mas quando você tem muitas listas de entradas torna-se quase impossível de gerenciar. Você precisa se isolar da corrente.
O que as setas permitem nos sistemas FRP é a composição das funções em uma rede e, ao mesmo tempo, abstrai inteiramente qualquer referência aos valores subjacentes que estão sendo passados por essas funções. Se você é novo em FP, isso pode ser confuso a princípio, e depois alucinante quando você absorveu as implicações disso. Você só recentemente absorveu a ideia de que as funções podem ser abstraídas e como entender uma lista como [(*), (+), (-)]
como sendo do tipo [(a -> a -> a)]
. Com as setas, você pode empurrar a abstração mais uma camada.
Essa capacidade adicional de abstração traz consigo seus próprios perigos. Por um lado, isso pode levar o GHC a casos que não sabem o que fazer com suas suposições de tipo. Você terá que estar preparado para pensar no nível do tipo - esta é uma excelente oportunidade para aprender sobre tipos e RankNTypes e outros tópicos.
Há também vários exemplos do que eu chamaria de "Stupid Arrow Stunts", onde o codificador alcança algum combinador de flechas apenas porque ele ou ela quer mostrar um truque com tuplas. (Aqui está minha própria contribuição trivial para a loucura .) Sinta-se livre para ignorar esse cachorro-quente quando você se deparar com ele na natureza.
NOTA: Como mencionei acima, sou um noob relativo. Se eu promulguei quaisquer equívocos acima, sinta-se à vontade para me corrigir.