Краткий ответ:
State
предназначен для использования возможностей монад для имитации императивного состояния системы с локальными переменными. Основная идея состоит в том, чтобы скрыть внутри монады деятельность по принятию текущего состояния и возврату нового состояния вместе с промежуточным результатом на каждом шаге (и здесь у нас есть s -> (a,s)
.
- Не путайте произвольные функции с функциями, заключенными в
State
. Первые могут иметь любой тип, который вы хотите (при условии, что они в конечном итоге производят несколько State a
, если вы хотите использовать их в монаде состояний). Последний содержит функции типа s -> (a,s)
: это уровень передачи состояния, управляемый монадой.
- Как я уже сказал, функция, заключенная в
State
, на самом деле создается с помощью (>>=)
и return
, как они определены для экземпляра Monad (State s)
. Его роль - передавать состояние через вызовы вашего кода.
Пункт 3 также является причиной того, что параметр состояния исчезает из функций, фактически используемых в монаде состояния.
Длинный ответ:
Государственная монада изучалась в разных статьях, а также существует во фреймворке Haskell (сейчас я не помню хороших ссылок, я добавлю их как можно скорее).
Это идея, которая следует из этого: рассмотрим тип data MyState = ...
, значения которого содержат текущее состояние системы.
Если вы хотите передать его через кучу функций, вы должны написать каждую функцию таким образом, чтобы она принимала по крайней мере текущее состояние в качестве параметра и возвращала вам пару с ее результатом (в зависимости от состояния и другого ввода параметры) и новое (возможно, измененное) состояние. Что ж, это именно то, что вам говорит тип монады состояния: s -> (a, s)
. В нашем примере s
равно MyState
и предназначен для передачи состояния системы.
Функция, заключенная в State
, не принимает параметров, кроме текущего состояния, которое необходимо для получения в результате нового состояния и промежуточного результата. Функции с большим количеством параметров, которые вы видели в примерах, не являются проблемой, потому что, когда вы используете их в do
-нотации внутри монады, вы применяете их ко всем «лишним» необходимым параметрам, что означает, что каждый из них будет привести к частично примененной функции, единственным оставшимся параметром которой является состояние; экземпляр монады для State
сделает все остальное.
Если вы посмотрите на тип функций (на самом деле, внутри монад они обычно называются действиями), которые могут использоваться в монаде, вы увидите, что их тип результата заключен в рамку внутри монады: это точка, которая говорит вам, что как только вы дадите им все параметры, они фактически вернут вам не результат, а (в данном случае) функцию s -> (a,s)
, которая будет соответствовать законам композиции монады.
Вычисление будет выполнено путем передачи всему блоку / композиции первого / начального состояния системы.
Наконец, функции, которые не принимают параметры, будут иметь тип типа State a
, где a
- их тип возвращаемого значения: если вы посмотрите на конструктор значения для State
, вы снова увидите, что это на самом деле функция s -> (a,s)
.
person
Riccardo T.
schedule
19.04.2012