Я понимаю, что опаздываю на вечеринку, но у вас здесь есть два теоретических ответа, и я хотел предоставить практическую альтернативу пережевыванию. Я подхожу к этому как относительный новичок Хаскелла, который, тем не менее, недавно подвергся насильственному маршу по теме «Стрелы» для проекта, над которым я сейчас работаю.
Во-первых, вы можете продуктивно решать большинство проблем в Хаскеле, не доходя до Стрелок. Некоторые известные Haskellers искренне не любят и не используют их (см. Здесь , здесь , и здесь для получения дополнительной информации об этом). Поэтому, если вы говорите себе «Эй, мне это не нужно», поймите, что вы действительно можете быть правы.
Что меня больше всего огорчило в Arrows, когда я впервые узнал о них, так это то, как учебные материалы по этой теме неизбежно достигли аналогии со схемой. Если вы посмотрите на код стрелки - по крайней мере, на подслащенный вариант - он больше не похож на язык аппаратного определения. Ваши входы располагаются справа, ваши выходы слева, и если вы не подключите их все правильно, они просто не сработают. Я подумал про себя: правда? Это то, где мы оказались? Мы создали язык настолько высокого уровня, что он снова состоит из медных проводов и припоя?
Насколько я смог определить, правильный ответ на этот вопрос таков : на самом деле, да. В настоящий момент убийственный сценарий использования Arrows - это FRP (вспомним Yampa, игры, музыку и реактивные системы в целом). Проблема, с которой сталкивается FRP, в значительной степени та же проблема, с которой сталкиваются все другие системы синхронного обмена сообщениями: как связать непрерывный поток входных данных в непрерывный поток выходных данных без потери соответствующей информации или возникающих утечек. Вы можете смоделировать потоки в виде списков - несколько последних систем FRP используют этот подход - но когда у вас много входных списков, управлять ими практически невозможно. Вам нужно оградить себя от течения.
Что позволяет стрелкам в системах FRP, так это составление функций в сеть, в то же время полностью абстрагируя любые ссылки на базовые значения, передаваемые этими функциями. Если вы новичок в FP, это может сначала сбить вас с толку, а затем и ошеломить, когда вы осознаете последствия этого. Вы только недавно освоили идею о том, что функции могут быть абстрагированы, и как понимать список как имеющий [(*), (+), (-)]
тип [(a -> a -> a)]
. С помощью стрелок вы можете продвинуть абстракцию еще на один уровень.
Эта дополнительная способность к абстракции несет в себе свои опасности. С одной стороны, это может подтолкнуть GHC в угловые случаи, когда он не знает, что делать с вашими предположениями типа. Вы должны быть готовы думать на уровне типов - это отличная возможность узнать о типах, RankNTypes и других подобных темах.
Есть также ряд примеров того, что я бы назвал «Тупыми трюками со стрелками», когда кодировщик тянется к какому-то комбинатору стрелок только потому, что он или она хочет показать аккуратный трюк с кортежами. (Вот мой собственный тривиальный вклад в безумие .) Не стесняйтесь игнорировать такие хот-дог, когда вы сталкиваетесь с этим в дикой природе.
ПРИМЕЧАНИЕ: как я уже упоминал выше, я относительный нуб. Если я обнародовал какие-либо заблуждения, пожалуйста, поправьте меня.