Что такое хороший способ для разработки / структурирования больших функциональных программ, особенно в Haskell?
Я прошел через кучу уроков («Пишу себе схему» - моя любимая, с «Реал Уорлд Хаскелл»), но большинство программ относительно небольшие и одноцелевые. Кроме того, я не считаю некоторые из них особенно элегантными (например, огромные таблицы поиска в WYAS).
Теперь я хочу писать более крупные программы с большим количеством движущихся частей - собирать данные из различных источников, очищать их, обрабатывать их различными способами, отображать в пользовательских интерфейсах, сохранять их, общаться по сетям и т. Д. Как можно Лучше ли структурировать такой код, чтобы он был удобочитаемым, поддерживаемым и адаптируемым к меняющимся требованиям?
Существует достаточно большая литература, посвященная этим вопросам для крупных объектно-ориентированных императивных программ. Такие идеи, как MVC, шаблоны проектирования и т. Д., Являются подходящими рецептами для реализации широких целей, таких как разделение задач и повторное использование в стиле ОО. Кроме того, новые императивные языки поддаются «рефакторингу» в стиле «дизайн по мере роста», который, по моему мнению новичка, выглядит менее подходящим для Haskell.
Есть ли эквивалентная литература для Haskell? Как зоопарк экзотических структур управления, доступных в функциональном программировании (монады, стрелки, аппликативные и т. Д.), Лучше всего использовать для этой цели? Какие лучшие практики вы можете порекомендовать?
Спасибо!
РЕДАКТИРОВАТЬ (это продолжение ответа Дона Стюарта):
@dons упомянул: «Монады захватывают ключевые архитектурные проекты в типах».
Я предполагаю, что мой вопрос: как следует думать о ключевых архитектурных проектах на чистом функциональном языке?
Рассмотрим пример нескольких потоков данных и нескольких этапов обработки. Я могу написать модульные парсеры для потоков данных для набора структур данных, и я могу реализовать каждый шаг обработки как чистую функцию. Шаги обработки, требуемые для одного куска данных, будут зависеть от его значения и других. Некоторые шаги должны сопровождаться побочными эффектами, такими как обновления графического интерфейса или запросы к базе данных.
Какой «правильный» способ связать данные и этапы синтаксического анализа хорошим способом? Можно написать большую функцию, которая делает правильные вещи для различных типов данных. Или можно использовать монаду для отслеживания того, что было обработано до сих пор, и чтобы каждый шаг обработки получал все необходимое из состояния монады. Или можно написать в значительной степени отдельные программы и отправлять сообщения (мне не очень нравится этот вариант).
На слайдах, которые он связал, есть пункт «Вещи, которые нам нужны»: «Идиомы для отображения дизайна на типы / функции / классы / монады». Какие идиомы? :)