Творческое использование монад

Я ищу творческое использование монадов, чтобы учиться. Я где-то читал, что монады использовались, например, в ИИ, но, будучи новичком монады, я не понимаю, как это сделать.

Укажите ссылку на исходный код и примеры использования. Нет стандартные монады, пожалуйста.

Ответ 1

Фил Вадлер написал много статей о монадах, но тот, кто первым читает, очень забавна и будет доступна любому программисту; он называется Суть функционального программирования. Документ включает исходный код и примеры использования.

Личным моим фаворитом является вероятностная монада; если вы можете найти Sungwoo Park кандидатскую диссертацию, у него есть ряд интересных примеров из робототехники.

Ответ 2

Там также LogicT (переход от монопольного преобразования с справедливыми операциями и обрезкой).

Он имеет хорошее значение для алгоритмов поиска AI из-за его конструкций для справедливых дизъюнкций, например, легко позволяет вычисления, которые с успехом используются бесконечно много раз (чередуются).

Это использование описано в документе ICFP'05 Backtracking, Interleaving и Terminating Monad Transformers

Ответ 3

вы можете найти интересные и продвинутые монады в блоге The Neighborhood of Infinity. Я могу отметить Vector Space Monad, и его использование для рациональных путаниц описание. К сожалению, я не думаю, что понимаю это достаточно хорошо, чтобы объяснить это здесь.

Ответ 6

Harpy, пакет для генерации машинного кода x86 во время выполнения, использует генерация кодов поколения. Из описания:

Это объединенная монада-исключение-состояние, которая обрабатывает все детали обработки буферов кода, испускает двоичные данные, перемещение и т.д.

Все функции генерации кода в модуле Harpy.X86CodeGen живут в этой монаде и используют свои средства отчетности об ошибках, а также внутреннее состояние, поддерживаемое монадой.

Пользователь библиотеки может передавать пользовательскую среду и пользовательское состояние через монаду. Это состояние не зависит от внутреннего состояния и может использоваться библиотеками генерации более высокого уровня для поддержания собственного состояния при выполнении операций генерации кода.

Я нашел это особенно интересным примером, потому что я думаю, что этот шаблон не редкость: я изобрел что-то очень похожее для создания набора внутренних сообщений для моего приложения на основе сообщений, полученных из фида (база данных), Оказывается, это чрезвычайно удобный способ иметь структуру, отслеживающую различные "глобальные" вещи при составлении простых операций, которые сами по себе не сохраняют состояния.

Я сделал еще один шаг к его идее о наличии пользовательского состояния (которое я называю "подстанцией" ), которое также может быть передано через монаду: у меня есть механизм для переключения и восстановления состояния во время выполнения монады:

-- | Given a generator that uses different substate type, convert it
-- to a generator that runs with our substate type. As well as the
-- other-substate-type generator, the caller must provide an initial
-- substate for that generator and a function taking the final substate
-- of the generator and producing a new substate of our type. This
-- preserves all other (non-substate) parts of the master state touched
-- by the generator.
--
mgConvertSubstate :: MsgGen msg st' a -> st' -> (st' -> st) -> MsgGen msg st a

Это используется для подгрупп комбинаторов, у которых было свое собственное состояние в течение короткого периода времени. Они выполняются только с их состоянием, не зная ничего о состоянии генератора, который его вызывал (что помогает сделать вещи более модульными), и все же это сохраняет любое состояние, не относящееся к пользователю, такое как текущий список генерируемых сообщений и текущий набор предупреждений или ошибок, а также поток управления (т.е. разрешить полное прерывание потока вверх).

Ответ 7

Одно интересное использование монады заключается в разборе. Parsec является стандартным примером.

Ответ 8

Я хотел бы перечислить пару монадов, еще не упомянутых в других ответах.

Перечислить и взвешенные поисковые монады

Мода Omega может использоваться для продуктивного прохождения бесконечных списков результатов. Для сравнения:

>>> take 10 $ liftM2 (,) [0..] [0..]
[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9)]

>>> take 10 $ runOmega $ liftM2 (,) (each' [0..]) (each' [0..])
[(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)]

С более продвинутой WeightedSearch monad также можно назначить веса вычислениям, чтобы появлялись результаты вычислений с более низкими весами сначала на выходе.

Накопительные ошибки monad

Полезный These тип данных формирует a Monad, аналогичный Either, но способный скорее накапливать ошибки. Пакет также определяет MonadChronicle класс, а также ChronicleT monad transformer на основе These.