Нет, это не то, что монады вообще делают. Тем не менее, ваша аналогия на самом деле в точности верна в отношении типа данных State s a
, который оказывается a монадой. State
определяется следующим образом:
newtype State s a = State { runState :: s -> (a, s) }
... где переменная типа s
- это значение состояния, а a
- это "обычное" значение, которое вы используете. Таким образом, значение в «Монаде состояния» - это просто функция от начального состояния до возвращаемого значения и конечного состояния. Монадический стиль, применяемый к State
, не делает ничего, кроме автоматической передачи значения состояния через последовательность функций.
Монада ST
внешне похожа, но использует магию, чтобы позволить вычисления с реальными побочными эффектами, но только так, что побочные эффекты не могут наблюдаться извне определенных случаев использования ST
.
Монада IO
- это, по сути, монада ST
, настроенная на "больше магии", с побочными эффектами, которые затрагивают внешний мир, и только в одной точке, в которой выполняются вычисления IO
, а именно точка входа для всего программа. Тем не менее, на некотором концептуальном уровне вы все еще можете думать о нем как о потоке значения «состояния» через функции, как это делает обычный State
.
Тем не менее, другие монады не обязательно имеют какое-либо отношение к состоянию потоков, функциям секвенирования или к чему-либо еще. Операции, необходимые для того, чтобы быть монадой, являются невероятно общими и абстрактными. Например, использование Maybe
или Either
в качестве монад позволяет использовать функции, которые могут возвращать ошибки, при этом обработка монадического стиля выходит из вычисления, когда ошибка происходит так же, как State
передает значение состояния. Использование списков в качестве монады дает вам недетерминированность , позволяя вам одновременно применять функции к нескольким входам и видеть все возможные выходы, причем монадический стиль автоматически применяет функцию к каждому аргументу и собирает все выходы.