, используйте функцию
>state
, которая делает то же самое, что делал бы конструктор
>State
.
Теперь, когда вы увидели, в чём заключается суть вычислений с состоянием и как их можно даже воспринимать в виде значений с контекстами, давайте рассмотрим их экземпляр класса >Monad
:
>instance Monad (State s) where
> return x = State $ \s –> (x, s)
> (State h) >>= f = State $ \s –> let (a, newState) = h s
> (State g) = f a
> in g newState
Наша цель использования функции >return
состоит в том, чтобы взять значение и создать вычисление с состоянием, которое всегда содержит это значение в качестве своего результата. Поэтому мы просто создаём анонимную функцию >\s –> (x, s)
. Мы всегда представляем значение >x
в качестве результата вычисления с состоянием, а состояние остаётся неизменным, так как функция >return
должна помещать значение в минимальный контекст. Потому функция >return
создаст вычисление с состоянием, которое представляет определённое значение в качестве результата, а состояние сохраняет неизменным.
А что насчёт операции >>>=
? Ну что ж, результатом передачи вычисления с состоянием функции с помощью операции >>>=
должно быть вычисление с состоянием, верно? Поэтому мы начинаем с обёртки >newtype State
, а затем вызываем анонимную функцию. Эта анонимная функция будет нашим новым вычислением с состоянием. Но что же в ней происходит? Нам каким-то образом нужно извлечь значение результата из первого вычисления с состоянием. Поскольку прямо сейчас мы находимся в вычислении с состоянием, то можем передать вычислению с состоянием >h
наше текущее состояние >s
, что в результате даёт пару из результата и нового состояния: >(a,
>newState)
.
![](data:image/png;base64,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
xFkEiXP0AAAAAElFTkSuQmCC)
До сих пор каждый раз, когда мы реализовывали операцию >>>=
, сразу же после извлечения результата из монадического значения мы применяли к нему функцию >f
, чтобы получить новое монадическое значение. В случае с монадой >Writer
после того, как это сделано и получено новое монадическое значение, нам по-прежнему нужно позаботиться о контексте, объединив прежнее и новое моноидные значения с помощью функции >mappend
. Здесь мы выполняем вызов выражения >f a
и получаем новое вычисление с состоянием >g
. Теперь, когда у нас есть новое вычисление с состоянием и новое состояние (известное под именем >newState
), мы просто применяем это вычисление с состоянием >g
к >newState
. Результатом является кортеж из окончательного результата и окончательного состояния!
Итак, при использовании операции >>>=
мы как бы «склеиваем» друг с другом два вычисления, обладающих состоянием. Второе вычисление скрыто внутри функции, которая принимает результат предыдущего вычисления. Поскольку функции